1. 系统分析

本章将从整体上描述系统的需求,根据需求确定了系统的整体结构和数据库设计方案,对系统各部分的功能进行了划分并描述了系统架构的设计思路。本文将详细的分析系统的续期功能的设计及实现方法。

研究背景

目前市面上已经有很多面包手机店专卖店铺,而且有很多店铺已经做出了不错的业绩,是全国连锁店。然而随着时代的进步,人们渐渐倾向于在线购物的消费方式。手机店的销售也应该与时俱进,加强自身的信息化建设,才能在越来越激烈的竞争中保持竞争优势。如今市场上也已经存在了此类的烘焙食品在线销售网站,但是现有的手机店在线销售网站还存在着商品单一、操作难、页面不美观、缺少后台管理等问题,还有很大的进步空间。这些问题因素也导致了网站在市场上的推广受到一定的限制。如何开发出成本低廉、功能齐全、页面美观的烘焙商城网站正是我们目前需要解决的问题。

目的和意义

本网站目的是方便广大用户在线购买自己喜欢的手机,打破传统购买方式促进消费,也让用户足不出户即可完成手机的购买,享受到食品的美味、、线上销售的数据也可以作为商家分析销售情况的基本数据来源。

  1. 系统可行性分析

应用的可行性包括许多方面,整体来讲可以概括为三点,首先是经济上的可行性,毕竟这是任何人都不得不面对的问题;其次,技术上也必须可行,不可脱离实际;最后,操作和法律上的可行性也是不可或缺的。经过一系列的研发之后,还有进行运行和实际操作,从发展的眼光来看,还要考虑这个系统的可持续发展性,一个成功的基于智能推荐的b2c销售网站平台,也许在硬件设备上是有一定的局限性,进一步的优化和创新乃至突破是非常重要的。

  1. 经济可行性

该系统的研发在经济上并没有非常大的需求,商品信息的获取也只需较少的费用。同时,目的也并非是十分的复杂,这样并不实用,研发的时间整体上来说很长,事实上它达到了为用户带来方便的目的,还可以让该应用有很大的发展空间,这样的话,那它所产生的回报会高于支出。Java平台是一个非常自由的平台,开发人员的经济支出其实是有限的。这样会在很大程度上提升该系统的高效性这一特点,然后就能为研发工作创造一个良好的条件和基础。结果证实,本系统的开发确实科学性较强。

  1. 技术可行性

该应用采用的是基于JavaEE开发,现阶段来讲,Java发展已经相当成熟,并且以Java为开发平台的研发日益增多,受到很多研发工作人员的欢迎。所以,技术层面上JavaEE其实是能够完成这个平台开发的任务。因此系统开发在技术上是可行的。

  1. 操作可行性

对于软件来讲,开发之后其操作难度决定了它能否受到大规模推广,这是研发者必须考虑的问题,而本基于智能推荐的b2c销售网站就非常易于操作。使用者能够拥有一个浏览器设备,根本就不需要指导,很自然的就能够自己学会使用,操作完全没有复杂性,因此,在开发这个软件的时候,我并没有提供提示或者帮助这类功能,这完全不影响。多以,该系统在操作上来说,都是广大群众非常熟练的模式,一切的操作都很简单,易于上手。

  1. 法律可行性

该系统无论在哪一方面都有十分详尽的考虑,包括技术,经济等等,事实上,它也绝不会有任何的法律问题,完全具有法律的可行性,其研发能够进行。

  1. 需求分析

1.2.1 系统目标

本系统的目标是要完成一个基于B/S架构的基于智能推荐的b2c销售网站功能的设计和开发。这些模块主要包括服装订购管理、用户管理、订单管理、商品管理等功能。实现对基于智能推荐的b2c销售网站信息进行管理,实现管理自动化,系统化,规范化。本系统开发过程主要采用基于SSM框架技术,使用JSP页面技术,后台数据库采用MySQL开发而成,保证查询,添加,删除,修改等功能。

1.2.2 用户需求和模块功能

1、注册用户:收藏管理、订单管理、地址管理、安全管理、购物车管理

2、管理员:商品管理、订单管理、用户管理、轮播图管理、评论管理、商品分类管理、账户管理

1.2.3 系统业务流分析

  1. 软件系统的非功能分析

软件的非功能需求是约束系统、支持功能实现的相关需求,包括软件的效率、可靠性、安全性、可用性、适应性等。由于本软件的用户量较大应满足以下非功能需求:

  1. 效率:基于智能推荐的b2c销售网站数据库访问速度最大延迟为1秒,允许多个用户并行访问,访问站点不能超过2秒的延迟时间。
  2. 可靠性:保证系统正常工作,具有抗干扰能力,能够对系统检测并自动纠错。出现故障时不会发生崩溃,并且功能重新恢复。
  3. 安全性:保证信息的可用性、完整性、机密性、用户身份认证。
  4. 可用性:界面友好、容易学习、方便用户使用。
  5. 适应性:系统能能够适应外部环境及需求的变化。

1.4 设计目标

设计与实现一个基于智能推荐的b2c销售网站。能够辅助管理员对基于智能推荐的b2c销售网站信息的管理。

在构建系统时,根据不同的模块的特点和功能,新系统必需满足以下目标:

(1)稳定性:保证系统能够稳定的运行,部分硬件的变化不会影响到系统的整体运行,同时系统的运行也不会受到其他错误模块的影响。

(2)准确性:根据官方的操作指南,使用系统管理员操作所产生的“权限数据”,应该是符合所有数据库的实际状态,它是禁止记录错误和错位数据等现象。

(3)开放性:系统可以在保证兼容性的硬件基础上,进行多个站点的操作,作为在Java平台的基础上架构的该系统具有独立的平台,在不同的环境下,具有独立处理能力。

(4)可扩展性:如果有新的业务增加,不需要改变原有系统,你只需要进行扩展。

(5)可维护性:接口参数的变化不需要再写代码,从而大大方便了二次开发。

(6)独立性:尽量减少模块之间的链接,这样用户可以自主选择模块需要安装或不需要安装的模块。

(7)易使用性:系统的用户界面和操作员之间的交互性非常的好,同时和主机使用B/S模式。

(8)先进性:使系统能够跟上技术的发展,不过时。在保证系统稳定性的前提下,我们可以尝试更多的国际上的流行技术。

  1. .4相关技术以及开发工具

经过第一章节的介绍,已经对课题的研究背景、现状及目的有了初步的理解,接下来介绍在设计实现该系统的过程中所使用到的技术和开发工具。

1.4.1相关技术

  1. Spring简介

Spring框架是个轻量级的Java开放源代码的技术框架,主要用来管理后段业务各类的Bean对象。其面向切面的编程思想贯穿整个系统的设计过程,以此来实现业务逻辑层与其他层次的解耦,大大的减少了开发人员的工作量。在Spring出现前,开发者需要将配置大量的xml以及编写大量的Servlet配置类,手动的创建大量的对象以实现对对象的引用。而早期的EJB规范是为了简化分布式系统的开发,虽然EJB的出现却有其先进性,但是随着时间的推移,开发者们渴望诞生一种技术能够弥补EJB的缺陷,由此Spring便应运而生。

  1. MyBatis简介

Mybatis是一种数据库管理框架。前身是Java开源框架ibatis,mybatis框架之所以使用量比是hibernate多,是因为它不同于hibernate的全局性,Mybatis的sql语句非常的灵活,便于更改,是一种弱对应的框架(hibernate是一个强对应的持久化框架),你可以自己在mapper相关的xml文件中轻松的配置对应关系,或者你可以在Java代码中通过竹节轻松编写SQL语句,实现开发0配置,极大的简化了开发人员的工作,降低了开发难度。

  1. Tomcat服务器

Tomcat是一个免费的轻量级的用于发布中小型项目的JavaWeb服务器,Tomcat虽属于Apache基金会,但是他与Apache服务器不同,他是一个独立的服务器,与Apache相辅相成,可以这么说,Tomcat服务器是Apache的一个独立的进程单元。

  1. Navicat简介

Navicat 相对来说比较小巧可靠轻盈的数据库管理工具,相对于workbench的笨重,Navicat非常的快速,很适合小型企业或者学术研究使用,它支持连接多种数据库,同时,它还能够集成目前市场上的多品牌(例如:阿里云,亚马逊云)的云数据库。并且它可以对MongoDB、MySQL、Oracle、SQL Server等主流数据库进行支持和管理,非常适合本实验使用,所以选择了Navicat而并未选择其他数据库管理工具。

  1. 本章小结

本章主要介绍系统开发与实现过程中所使用到的相关技术及开发工具,包括SpringMVC框架、MyBatis技术、Eclipse开发环境、Tomcat服务器和MySQL数据库等。

  1.  系统设计

概要设计的主要任务是把需求分析得到DFD转换为软件结构和数据结构。设计软件结构的具体任务是:将一个复杂系统按功能进行模块划分,建立模块的层次结构及调用关系,确定模块间的接口及人机界面等。数据结构设计包括数据特征的描述,确定数据的结构特性,以及数据库的设计,显然,概要设计建立的是目标系统的逻辑模型,与计算机无关。

2.1 系统功能模块

经过对系统的需求分析的了解,我们对系统的功能模块进行了划分,图2.1是本系统所涉及的功能模块图。

  1. 注册用户:收藏管理、地址管理、购物车管理、安全管理、订单管理

图2.1 功能模块

  1. 管理员:商品管理、订单管理、用户管理、轮播图管理、评论管理、商品分类管理、账户管理。

图2.1 功能模块

2.2 数据库设计

在一个数据库应用系统的开发过程中,数据库的设计是整个系统的基础。良好的数据结构设计不仅可以减少数据冗余、提高查询效率,而且还可以降低应用程序的编写难度,提高工作效率。

2.2.1 数据库概要设计

概念设计是在分析数据的基础上建立了系统的分析和数据库设计,然后从前面分析的角度,将设计的观点整合在一起,最终完成了系统的结构分析和优化设计。

一般的数据库结构的概念,是一个实体和属性的关系模型。E-R模型一般拥有实体、属性和联系等多方面的信息,E-R模型采用的是E-R图来表示,需要提示用户工作中所以需要用到的事物,属性则是对实体信息的表述。

概念设计的目标是需要反映出系统所要求的数据库概念的结构,也就是概念模型。概念模式是独立于数据库的逻辑结构的,并且是一个独立的DBMS,不需要去依赖计算机系统的。

根据以上对数据库的需求分析,并结合系统概念模型的特点及建立方法,建立E-R模型图。

2.2.2 E-R关系模式的转换

关系模型的逻辑结构是一组关系模式的集合。E-R图则是由实体,实体的属性和实体间的联系三个要素组成。所以将E-R图转换为关系模型实际上就是要将实体,实体的属性和实体间的联系转换为关系模式。转换原则如下:

(1) 实体类型的转换:将每个实体类型转换成一个关系模式,实体的属性及为关系模式的属性,实体标识符及为关系模式的键。

(2) 联系类型的转换,根据不同的情况做不同的处理:

①若实体间的联系是1:1,可以在两个实体类型转换成的两个关系模式中的任意一个关系模式的属性中加入另一各关系模式的键和联系类型的属性。

② 若实体间的联系1:N,则在N端实体类型转换成的关系模式中加入1端实体类型转换成的关系模式的键和联系类型的属性。

③若实体间的联系是M:N,则将联系类型也转换成关系模式,其属性为两端实体类型的键加上关系类型的属性,而键为两端实体间的组合。

依照该规则将网上招聘求职系统的E-R图转换为关系模型如下:

将每一个实体转换成一个关系(关系就是给出关系名,写出属性,并标明该关系的主键)。

管理员信息(流水号,管理员帐号,管理员密码)

用户信息(流水号,姓名,编号,年龄,性别,用户名,密码,邮箱)

2.2.3 数据表结构

建立一个良好的数据库,需要追寻一下原则:

1. 尽量较少数据沉余和重复。

2. 操作设计和结构设计相结合。

3. 数据结构具有相对的稳定性。

根据系统的需求分析,同时又根据相关部分数据流程,本系统共创建了6张表,

以下为数据库中的表:

数据库名:phonemarket2

表名:userd

源码下载地址:​​https://download.csdn.net/download/itrjxxs_com/22174377​​

摘 要

21世纪是一个知识大爆炸的时代,互联网拉近了人们的距离,信息化革命席卷了各个行业。物质生活水平的提高使得人们的消费观念悄然发生改变,人们对户外旅行的要求越来越高,这对于传统旅游行业来说既是机遇也是挑战。提高旅游行业管理水平、推进旅游行业信息化已势在必行,旅游网站的出现为此提供了有力的保证。

旅游网站的系统设计是基于JSP技术的,它具有灵活的一体化发展战略,圆满完成了整个系统的全面设计。旅游网站,采用一个简单的界面,操作方便,灵活,实用,有效的简化了传统的旅游流程,大大提高了人们获取信息的效率,使之更加系统化体系化,标准化,自动化,具有优良的可用性,可靠性,安全性。主要采用JSP技术开发,提高运行性能,安全性和系统性能,并且易于维护和操作。

关键词 旅游网站;ServletMySQL数据库

ABSTRACT

The 21st century is an era of knowledge explosion. The Internet has brought people closer, and the information revolution has swept across various industries. The improvement of material living standards has caused people's consumption concepts to change quietly, and people's demands for outdoor travel are getting higher and higher, which is both an opportunity and a challenge for the traditional tourism industry. It is imperative to improve the management level of the tourism industry and promote the informationization of the tourism industry. The emergence of tourism websites has provided a strong guarantee for this.

The system design of the travel website is based on JSP technology. It has a flexible integrated development strategy and successfully completes the overall design of the entire system. The travel website adopts a simple interface, which is convenient, flexible and practical. It simplifies the traditional travel process and greatly improves the efficiency of people's access to information, making it more systematic, standardized, automated, and has excellent usability. , reliability, safety. Mainly developed with JSP technology to improve operational performance, security and system performance, and easy to maintain and operate.

Key words travel website; Servlet; MySQL database

  1. 绪论

1.1 课题研究背景及来源

随着经济文化的发展,人们的生活水平不断提高,旅游意识逐渐增强,旅游正逐步从消遣品过渡为必需品。互联网的普及,为实现足不出户就可以获取旅游最新的资讯攻略,为旅游资讯网站的发展创造了契机。因此,旅游资讯网站成为旅游业未来的一个主要发展方向。

这无疑是一种旅游方式的变革。但对于正站在变革边缘的我们,更需要正确的认识这次变革,它无疑是将我们从“信息时代”代入“概念时代”。在信息化时代中,我们已经能够拥有大量的信息,但是这些信息只经过简单的处理,并不能完全被用户使用。而概念时代推崇的是形象思维,它将掌管逻辑的左脑与富有想象力的右脑相结合,立志于将信息变得更加个性。

旅游业是国家战略性支柱产业,是极具发展潜力的“朝阳产业”、“绿色产业”。21世纪的中国将成为世界旅游大国,而城市的旅游资源在全国而言都具有显著优势,因而将旅游业作为支柱产业发展是符合城市市情的最佳选择,城市旅游资源比较丰富,旅游业发展迅速但其发展速度仍然相对较慢,为宣传城市旅游,利用JSP技术建立动态网站,实现旅游信息快速发布及接受游客的网上预定等功能的实现。设计一个网站,实现城市各旅游景点的游记攻略、出游活动、酒店住宿、新闻资讯,以及相关景点的flash展示。

1.2 网站应用技术

1.2.1 开发语言的选择

本系统是基于B/S模式设计的,在互联网领域当中,主流的web服务端开发语言有sun公司的java、微软的asp以及号称是世界上最好的编程语言的php。在大三教学课程中,我们专业系统学习了java编程语言,从巩固知识的角度出发,本系统选择java语言进行开发。但并不能说明其他编程语言不能进行本系统开发。下面将介绍java语言的优点以及选择java进行开发的优势。java以其健壮性、高性能、分布式、安全性等优点而脱颖而出[2],并且在连续十年来成为程序员最喜欢的编程语言之一。

1.2.2 开发工具的选择

主流的java IDE(Integrated Development Environment,集成开发环境)有 NetBeans、Eclipse、IntelliJ IDEA等。一个良好的开发工具能够达到事半功倍的效果,极大的提升开发效率。NetBeans是sun公司推出的java开发集成环境,但国内使用较少。Eclipse是一款开源的、使用java语言开发的的可扩展的集成开发环境,具有代码检测、自动编译、自动构建等特性。IntelliJ IDEA是JetBrains公司的产品,发布后便立即蚕食Eclipse市场份额。IntelliJ有一下优点:1.智能提示功能。IntelliJ 基于语法树的智能提示,自动完成使得IDE比notepad更加优秀,在这个领域能感知上下文的IDEA有了质的飞跃。2.代码重构,IDEA的重构功能也很聪明智能。它能读懂你需要什么,然后针对不同的情况提供给你最适合的解决方案。3.界面流畅,响应迅速,不会出现像Eclipse那样打开视图过多导致系统卡顿。

1.2.3 数据库的选择

在关系型数据库中,比较出色的有微软的Sql Server、甲骨文公司的Oracle数据库、以及开源数据库MySQL(被Oracle收购)。前两者为商业数据库,并且属于重量级数据库,虽然性能高,吞吐量大,但是占用系统资源较多,后期维护较困难。MySQL是一款开源免费的关系型数据库,运行速度快,容易使用,简单方便,支持标准的SQL查询语言,功能强大并且易于维护[3]。因此,选择MySQL作为本系统的存储系统十分合适。

1.2.4 服务器架构的选择

本开管理系统基于http协议进行数据传输的,市面上的Servlet Web容器有JBoss服务器、WebLogic 服务器、Tomcat服务器等。其中JBoss是一个种遵从JavaEE(Java Platform,Enterprise Edition,java企业级开发平台)规范的、开放源代码的、纯Java的EJB服务器,对于J2EE有很好的支持。JBoss采用JML API实现软件模块的集成与管理,其核心服务又是提供EJB服务器,不包含Servlet和JSP的Web容器,不过它可以和Tomcat完美结合。但由于JBoss过于繁重,本次系统中只用到Servlet容器一部分,因此Tomcat服务器是最佳选择。Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。

1.2.5 前后台显示界面选择

在B/S模式中,用户看到浏览器端的界面大多是采用HTML、CSS、JAVASCRIPT [4]来展示界面。说起前端界面,不得不提起现在一个十分火的前端项目—BootStrap框架。BootStrap 是一个用于快速开发 Web 应用程序和网站的前端框架。BootStrap 是基于 HTML、CSS、JAVASCRIPT 的。BootStrap易于上手,只要开发者具备 HTML 和 CSS 的基础知识,就可以开始学习和使用 BootStrap。它为开发人员创建接口提供了一个简洁统一的解决方案,包含了功能强大的内置组件,易于定制[5]。总之,BootStrap 包含了十几个可重用的组件,用于创建图像、下拉菜单、导航、警告框、弹出框,全局的 CSS 设置、定义基本的 HTML 元素样式、可扩展的 class,以及一个先进的网格系统。BootStrap对于创建一个简洁、美观的用户系统有很大帮助。

1.3 研究的目的和意义

毕竟现今网络的发展可以说是一日千里,透过网络的运用,尤其是现阶段最热门的电子商务的推动,未来的销售模式,将由传统的销售模式,逐步改为网络直销的方式,我们只要透过网络在现有的旅游攻略平台,创意性的结合销售模式,一定会给大家带来耳目一新的感觉。对于使用者而言它是一个相当简易的界面,不需要太深奥的电脑知识便可轻易上手,提供很丰富的旅游资料给使用者参考。网络充裕的资讯方便了网络使用者去享受,去运用,这样的模式满足了使用者的资讯需求,让使用者直接透过网络查询到自己的需求,加速自主旅游的趋势,同时能让使用者根据自己的喜好与分享者一同制定出独特的旅游路线,也可以购买自己有兴趣的纪念品。另外,网络的好处在于没有使用人数的限制,也没有地域,空间的限制,更没有时间的限制,任何时候,任何人都可以透过网络来浏览的页面,相同的也可以在任何时候悠游到网络的任何角落。在计算机上,进行一次愉悦而又短暂的环球旅行。

1.4 论文组织结构

本论文主要由六个章节组成,每个章节介绍如下:

第一章:绪论。本章主要介绍了我国旅游业信息化过程中出现的问题以及本课题研究的背景来源,并说明本论文的研究目的和意义。

第二章:系统总体需求分析与设计。本章介绍了本系统的总体需求分析,系统的设计思路与方案,开发环境、存储系统、服务器的选择,以及系统的总体架构。

第三章:数据库的详细设计,包括各个表的主键设计、字段的长度及类型设计。

第四章:系统实现。本章介绍了系统各个模块的界面展示,系统重要模块的操作流程,代码实现、系统运行所需要的环境,部署注意事项。

第五章:系统调试与测试。本章介绍了系统调试,系统测试,系统维护。例举了两个模块的测试案例以及系统维护的建议。

第六章:总结。本章总结了系统的优缺点,分析了系统的不足以及对未来工作提出展望。

  1. 系统总体需求分析与功能设计

2.1 总体需求分析

在系统需求分析阶段,搞清楚了要开发的这个软件需要“做什么”的问题,形成一个系统目标的逻辑模型来。然后我们所要做的就是要把软件需要“做什么”的这个逻辑模型转换成“怎么做”的一个物理模型,最后再着手实现系统的需求。首先,我们需要描述的是系统的总的体系结构。

系统不仅要求功能完善,而且还要界面友好,因此,对于一个成功的系统设计,功能模块的设计是关键。由于本系统可执行的是一般性质的外出旅游工作,本系统具有一般适用性,其所实现的功能满足个人对日常性外出旅游的工作。系统设计的图像的数据流分析阶段的需要结构化设计的概要说明的基础上,根据映射到软件体系结构的某些程序。首先,整个系统分成几个小的模块,小的问题,然后,进一步细分模块,添加细节。

本旅游网站以旅游攻略发布、旅游线路发布、酒店预订、美食预订、景区图片和景区订票等功能为核心,其宗旨是及时、准确、完整发布游客所需要的相关信息,同时给游客带来方便和给公司创造利益。它的主要功能如下:

一、旅游线路信息发布以及预定功能:顾客可通网站查看相应的旅游线路信息和预定旅游景点门票功能,管理员可以在后台对旅游线路进行发布、更新,对于线路预定可以进行相应的处理。

二、酒店查询、预订功能:顾客可以通过网站查询酒店情况,同时还可以对合适的酒店进行预订。

三、旅游景点介绍功能:顾客在网站可以查看景区主要旅游景区和景点介绍信息,管理员可以在后台对旅游景点信息进行更新、修改和删除。

四、旅游攻略发布功能:顾客可以通过旅游网站查看景区最新的旅游资讯和旅游动态,网站管理员可以在后台发布、更新和删除旅游新闻。

五、旅游风景图片发布功能:游客可以通过网站查看景区最新的风光图片,可以点击小图看大图,图片按照相应的旅游景点分类,管理员可以上传和修改、删除图片信息。

六、旅游服务在线留言功能:游客可以通过网站查看一些景区旅游的注意事项和在景区旅游经常遇到的一些问题,管理员在后台可以对信息进行更新和修改、删除功能。总体结构图见2-1。

图2-1 系统总体结构图

2.2 网站的用例图

参与者

旅游者:注册用户与登录用户  管理员:注册用户/登录用户

在旅游网站上,前台用户不必进行登陆就可以查看旅游攻略、景点信息、旅游线路、酒店信息、旅游百货、交通检索等信息浏览,而进一步的预订景区门票、预订酒店、预订美食以及在线留言就需要用户登录才能获取权限。而管理员则必须登陆以后才能进行前台网站信息的维护管理操作。

图2-2 前台用户的用例图

图2-3 管理员用户的用例图。

2.3 网站顺序图

本网站再未进行登录的情况下拥有的权限包括:旅游攻略查看、旅游线路查询、旅游活动查看、酒店信息查看、景区信息浏览、其他用户网站留言以及交通检索,涉及到预定类等操作需要预留个人信息的必须进行登录,包括门票预订、酒店预订、美食预订和在线留言。

后台管理员则必须进行登录后才能显示所有管理菜单,对网站的旅游攻略、景点信息、线路信息、交通信息、酒店信息以及留言信息等进行维护和更新操作,同时还必须对客户的预订信息做出及时的预订信息状态变更。

图2-5 网站顺序图

2.4 网站状态图

网站的状态都是基于用户的登录行为,登录后进行管理员和前台用户的所有状态操作。

图2-6 网站状态图

  1. 数据库详细设计

数据库的设计是整个系统的重中之重,数据库设计得好对后面编程的实现可谓如虎添翼,数据库设计的差,对程序员来说那是非常痛苦的一件事。首先可以根据需求分析来制定数据库设计方案,先从中抽出对应的实体,再根据各个实体确定实体的属性。

对于一个旅游网站来说它在长期的运行过程中必定会产生大量的数据信息,所以它对数据库的要求是相当严格的,一般像MySql那样的规模比较小的数据库在网站刚上线是足够的,但随着网站运行的时间越长,数据库规模的问题就会暴露出来。

3.1 用户表设计

在MySQL数据库中用户表各个字段约束如表3-1所示,其中用户编号是主键,用来标识一条唯一记录。账号被设计成唯一键,在所有的用户中,账号唯一,不能有重复值出现。而其他字段如密码、姓名、用户类型用字符串存储。

表3-1 系统用户表

字段名

数据类型长度

是否为空

id

INT(11)

NOT NULL

createtime

DATETIME

NULL

creator

VARCHAR(255)

NULL

email

VARCHAR(255)

NULL

logtimes

INT(255)

NULL

nickname

VARCHAR(255)

NULL

PASSWORD

VARCHAR(255)

NULL

realname

VARCHAR(255)

NULL

sex

VARCHAR(255)

NULL

tel

VARCHAR(255)

NULL

username

VARCHAR(255)

NULL

xiangpian

VARCHAR(255)

NULL

rolename

VARCHAR(255)

NULL

    

3.2 其他表设计

在每一个应用程序中,数据库的设计是其中非常重要的部分,选择合适的数据库并创建合计的结构式开发程序时首要的问题。数据库将用mysql进行设计和管理。数据库安全性就是保证数据库信息的保密性,完整性,一致性和可用性,防止非法用户越权使用数据库从而窃取,更改或破坏数据库中数据,将提供一些安全措施来保证数据库的安全。

景点表用来记录线路信息、发布人和价格等信息。

表3-2 景点信息表

字段名

数据类型长度

是否为空

id

INT(11)

NOT NULL

title

VARCHAR(500)

NULL

pubren

VARCHAR(500)

NULL

pubtime

DATETIME

NULL

tel

VARCHAR(500)

NULL

kftime

VARCHAR(500)

NULL

des

TEXT

NULL

tupian

VARCHAR(500)

NULL

menpiao

VARCHAR(500)

NULL

表3-3 客房信息表

字段名

数据类型长度

是否为空

id

INT(11)

NOT NULL

jdid

INT(11)

NULL

NAME

VARCHAR(255)

NULL

price

DOUBLE

NULL

表3-4 订单信息表

字段名

数据类型长度

是否为空

id

INT(11)

NOT NULL

ddno

VARCHAR(255)

NULL

des

VARCHAR(255)

NULL

fahuoren

VARCHAR(255)

NULL

fahuotime

DATETIME

NULL

shraddress

VARCHAR(255)

NULL

shrname

VARCHAR(255)

NULL

shrtel

VARCHAR(255)

NULL

STATUS

VARCHAR(255)

NULL

title

VARCHAR(255)

NULL

totalprice

DOUBLE

NULL

xiadanren

VARCHAR(255)

NULL

xiadantime

DATETIME

NULL

totaljifen

DOUBLE

NULL

wlorderno

VARCHAR(255)

NULL

wltype

VARCHAR(255)

NULL

hdtitle

VARCHAR(500)

NULL

hdid

INT(11)

NULL

  1. 系统实现

本章第一小节主要介绍系统关键模块的实现细节以及系统界面展示,中间两小结介绍项目部署所需要的环境以及部署所需要主要的问题。

4.1 前台界面设计及部分代码实现

4.1.1 登录模块界面

如图4-1所示,上方是系统标题,中间是两个输入框,分别输入账号和密码。如果是新用户需要先进行注册,然后输入账号密码,最后点击按钮可以登录,如果登录失败会弹出提示信息,如果登录成功则跳转到系统主界面。

图 4-1 用户登录界面

用户登录一共分为以下几个简单的步骤,先要对用户输入的信息进行验证,比如输入信息的真假性,然后将信息通过程序传送至后台,后台程序将会从数据库中查询相应的条目,如找不到匹配的账号信息,则返回错误结果并提示输入的账号密码有误,若找到匹配信息则将用户输入的密码与找到条目的密码相比较,若成功,系统将允许用户登录等个人主页。

在用户模块的设计中,必须先完成业务逻辑层相应的各个action类的代码编写,之后再根据系统具体的要求,编写不同要求的数据库访问DAO。

4.1.2 旅游景点信息界面

网站主要采用静、动相结合的方式,即静态的主画面和动态的图片相结合。静态主页内容包括学首页、背景图片信息。旅游攻略、景点信息、酒店信息就是利用JAVA与数据库结合的技术建立数据库查询管理系统,采用交互式的动态的web画面来实现。 

本网站默认的页面index.jsp, index.jsp提供了各个分版块的链接,其本身具备动态显示景区信息功能。

首页显示景区是所有旅游景区之中被推荐的前几个,如果点击进入景区展示页面,可以查看所有信息,如果点击一个景区信息,则直接跳转入该景区的详细介绍页面。景区搜索支持模糊查询,即输入关键字系统自动为用户进行匹配。

用户旅游景点信息浏览界面如4-2所示。

图 4-2 查看旅游景点信息界面

4.1.3 在线留言界面

用户在线留言界面如4-3所示。

图 4-3 用户留言界面

4.1.4景点门票预订界面

用户浏览可下订单的信息时,如果感兴趣可以进行下订单,若用户没有登录,点击下订单会弹出提示信息,要求用户先登录,只有登录后才能进行下订单。本网站只有景区中已经发布价格的可以进行下订单。

景点门票预定界面如图4-4所示。

图 4-4景点门票预定界面

4.2 后台管理员模块的设计

管理员拥有本系统最高的管理权限,可以进行密码的修改、用户管理、酒店预订管理、游记管理、景点线路管理和退出系统的功能,管理员的及时管理将能保证系统高效的运行。

图 4-5 游记管理界面

在显示系统景点信息时会发现在添加足够多的景点信息的时候,一篇统计信息的长度往往会超出屏幕的长度,并且很有可能因为数据量太大而导致页面脚本在解析数据的时候,使浏览器缓存被占用过多而导致卡顿甚至浏览器崩溃。所以在平台这边对数据进行合理的分页就显得尤为重要。本系统在这个模块中为分为设计了专门的实体,适应于多种场合的分页,本系统的其他模块也采用相同的方法。

分页功能实现时主要体现在持久层数据库查询操作,在使用Limit关键字时需要的参数第一项为第几条数据,第二项参数为查询数据的条数,这里需要根据页面传递过来的pc即当前页数来确定第一项参数,而第二项参数为系统定义好的公共静态常量。如下是持久层分页功能实现的关键代码:

String sql = "select count(*) from v_student" + whereSql;

Number number = (Number) qr.query(sql, new ScalarHandler(), params.toArray());

int tr = number.intValue();// 得到了总记录数

sql = "select * from v_student" + whereSql + " limit ?,?";

params.add((pc - 1) * ps);// 当前页首行记录的下标

params.add(ps);// 一共查询几行,就是每页记录数

List<Student> beanList = qr.query(sql, new BeanListHandler<Student>(

Student.class), params.toArray());

图 4-6 景点管理界面

图 4-7 评价管理界面

4.2 环境搭建

本程序是标准的java web工程,若要运行本程序需要满足以下条件。

下载安装jdk 1.8 并且配置环境变量。

下载安装MySQL数据库5.5版本及以上,设置字符集编码为utf-8.

下载配置Tomcat 7.0及以上版本[8]。

由于篇幅问题,运行环境的搭建不是本文研究的主要内容,以上三个软件安装都比较简单,关于以上三个软件怎么安装,可以从互联网上搜索相关图文安装教程。

4.3 系统部署

本程序是标准的Java EE工程,源码会编译为docmanager.war包,部署时只需要将docmanager.war拷贝到 Tomcat Home /webapps路径下,启动Tomcat即可。更多部署细节,请参考5.1系统调试章节。

4.4 本章小结

本章主要展现了系统的几个主要界面以及后台代码的实现,后两小结主要介绍了系统部署运行时所需要的软件环境以及部署步骤。在界面设计及代码实现部分详细介绍了系统登录、旅游景点信息管理、在线留言、景点门票预订模块的界面展现,代码实现,以及用户操作流程。

  1. 系统调试与测试

5.1 系统调试

在一个项目开发完成之后,就需要将代码部署到服务器中进行调试。假设服务器中已经安装完4.2小结中必须的三个软件jdk,MySQL,Tomcat,下面将对这三个软件安装的正确性与否进行测试与调试,全部调试成功后,才能保证程序的正常运行。

1.jdk 测试

jdk安装完成后,需要配置环境变量。环境变量配置的原理是在操纵系统的环境变量中添加两个键值对。第一个键是JAVA_HOME,值为jdk的安装路径,第二个键是PATH,值为jdk目录下面的bin目录。将这两个键值对在操作系统中配置完成后,在控制台中输入 “java -version”命令,便可以正常输出当前jdk版本。

2.数据库测试

数据库安装完成后,需要配置字符集编码为UTF-8。配置方式为打开MySQL的安装路径,找到配置文件/etc/my.cnf,--在 [MySQLd] 标签下加上以下内容:

default-character-set = utf8,character_set_server = utf8 保存并退出,最后重启MySQL即可。

3.Tomcat 配置

Tomcat是一个web服务器,只有把程序放到Tomcat中才能用浏览器进行访问。在本系统中Tomcat还有另外一个功能,即文件服务器[9]。原理是在操作系统的磁盘上创建一个目录作为文件存放的根目录,并且将其于Tomcat相关联,这样就可以使用http协议访问该目录下面的文件。以windows系统为例,首先在D盘根目录创建一个文件夹FileRoot,以此文件夹作为文件系统根路径。如何将该路径于Tomcat相关联?在Tomcat/conf/Catalina/localhost下面创建一个myfileupload.xml文件,文件的内容是

<?xml version="1.0" encoding="UTF-8"?>

<Context

reloadable="true"  docBase="D: /FileRoot" debug="0">

</Context>

以上代码表示,在用http 协议访问/myfileupload 路径时,Tomcat就会从D:/FileRoot 路径下查找目标的资源。

例如:在D:/FileRoot路径下放置一个图片资源,名称为1.png,在浏览器中输入localhost:8080/myfileupload/1.png,在浏览器中正确返回该图片内容,说明配置正确,否则配置Tomcat失败。

以上三个步骤配置成功后,在项目的配置文件中,把数据库的连接信息配置为目标机的MySQL账号密码,依次启动MySQL服务器,启动Tomcat,在浏览器中正常访问项目的登录界面,如果登录成功,则系统调试成功。  

5.2 系统测试

软件测试就是在一个软件投入使用前,对软件进行需求分析,设计规格说明书和编码的最终复审,是软件质量保证的关键步骤[10]。软件测试的指标有多个方面,如性能测试,功能测试,系统资源使用率等。本小节主要关注系统的功能测试,由于篇幅限制,本小节将对景点门票预订模块与在线留言模块进行黑盒测试[11]。

测试案例1 景点门票预订测试

测试名称:景点门票预订测试

目的:测试景点门票预订功能

内容:用户完成预订在后台管理界面以及用户中心可以查询。

条件:酒店信息表、酒店预订信息表

测试用例:

测试用例

输入

输出

1

无,直接点击提交按钮

操作失败,房间数不能为空

2

房间数等基本信息,但没有填写联系电话

操作失败,联系电话不能为空

3

房间数、电话基本信息,预订人未填写

操作失败,请填写预定人

结论:与预期结果相符合

测试案例2 在线留言

测试名称:在线留言测试

目的:用户添加留言,测试功能是否正常

内容:留言是否记录到数据库中

条件:留言信息表

测试用例:

测试用例

输入

输出

1

没有填写任何内容直接提交

操作失败,请填写标题

2

填写标题,但未填写内容

操作失败,未填写内容

3

添加留言,数据合法

操作成功,成功添加到数据库中

结论:与预期结果相符。

5.3 系统维护

一个正常的软件系统中,在运行期间难免会出现问题,因此需要进行不定期的系统维护。在系统中出现的问题大致分为两大类问题:硬件资源问题和软件问题。下面针对硬件资源和软件问题分别展开讨论系统维护的考虑因素。

关于硬件资源,本系统是一个旅游类网站,需要频繁的读取写入文件,如果文件数量过多,磁盘空间可能不够用,因此运维人员须用定时的查看磁盘的使用空间,例如使用率达到了75%之后,就要考虑增加磁盘阵列,对磁盘进行扩容。当发现磁盘写入、读取速度过慢,严重影响系统的使用体验,就要考虑更换更好的存储介质,如固态硬盘等。如果遇到网络传输问题,例如打开网站页面速度缓慢,经常发生超时现象,可能是发生了网络拥塞现象,例如可以增大网络带宽[12]。还有例如机器老化问题等,可以定期的更换服务器,以提高系统响应时间。

关于软件问题,例如某个模块出现了bug,这是代码的逻辑错误,此时必须升级代码,我们的代码是开源的,托管在github上[13],任何人都有权利修改代码,修改后重新编译打包,部署到服务器项目中即可。另外,项目中所有的资源使用通过maven构建的,将github上面的代码下载到本地后,可以执行mvn clean install packge[14] 命令来实现代码打包,最后在target目录下面生成docmanager.war包。部署步骤参考4.3小结。本系统的数据存储采用MySQL服务器,如果查询速度较慢,可以适当增加索引,另外当数据量达到一定规模后,为了提高系统吞吐量,可以采用数据库份库分表、读写分离等策略。如果遇到软件使用习惯、功能添加等问题,就必须修改源码,重新部署程序了。

总之,找到问题的原因,分析并且解决问题,是软件运行和维护的宗旨。

5.4 本章小结

本章介绍了系统完成的后续问题,系统调试、系统测试与维护。系统调试是调试系统所需的软件系统的调用关系,保证各个软件系统之间的通讯正常。系统测试主要介绍了系统的功能性测试,保证系统实现达到设计之初的要求。系统维护模块提出了系统在运行过程中可能出现的问题以及解决方案。

表名:admin

序号

列名

数据类型

长度

主键

外键

允许空

默认值

说明

1

Admin-id

Varchar

32

2

Admin-name

Varchar

32

3

Admin-pass

Varchar

32

4

Admin-phone

Varchar

32

5

Admin-date

Datetime

6

Admin-state

Varchar

2

1

7

Admin-role

Varchar

3

1

表名:address

序号

列名

数据类型

长度

主键

外键

允许空

默认值

说明

1

Addr-id

Varchar

32

2

Addr_province

Varchar

32

3

Addr-city

Varchar

32

4

Addr-area

Varchar

32

5

Addr-detail

Varchar

32

6

Addr-phone

Varchar

32

7

Addr-nickname

Varchar

32

8

Addr-state

Varchar

1

表名:goods

序号

列名

数据类型

长度

主键

外键

允许空

默认值

说明

1

Goods-id

Varchar

32

2

Goods-name

Varchar

32

3

Goods-price

Double

10

4

Goods-num

Int

32

5

Goods-type

Varchar

32

6

Goods-memory

Varchar

32

7

Goods-color

Varchar

32

8

Goods-img

String

9

Goods-state

Varchar

2

1

10

Goods-desc

Varchar

1000

11

Goods-volume

Varchar

10

表名:order

序号

列名

数据类型

长度

主键

外键

允许空

默认值

说明

1

Order-id

Varchar

32

2

Order-user

Varchar

32

3

Order-date

Datetime

4

Order-price

Double

32

5

Order-state

Varchar

5

6

Order-username

Varchar

32

7

Order-phone

Varchar

32

8

Order-address

Varchar

100

9

Order-expressno

Varchar

32

3 系统实现

系统实现是软件工程中软件开发的一个步骤,就是对概要设计的一个细化,就是详细设计每个模块实现算法,所需的局部结构。详细设计的主要任务是设计每个模块的实现算法,所需的局部数据结构。

本章将使用图形,代码,语言等工具将系统的每个模块处理过程的详细算法描述出来。

3.1 用户登录

用户登陆模块最基本的作用是为了限制该管理系统资源的使用,只有经过身份确认的操作员才能对其个性化电子商务推荐系统进行相关操作。其基本过程是从客户端取得提交的用户名和密码,然后到数据库中进行核对。如果该信息在数据库中存在,那么就可以成功登录到下一界面,否则就会被该系统拒之门外。

选择连接数据库后,进入用户登陆界面。在用户登陆界面中输入用户名和密码,从数据库表中检查是否有相应的用户名和密码。如果用户名和密码错误,系统就会给出错误提示,并且不会有任何的页面跳转。如果输入的用户名和相应密码正确,则可以点击“确定”进入主控制平台。用户登录的界面如图3.1所示。

3.1 登录界面

3.2 用户注册

用户点击网站首页的注册链接并跳转到注册页面,在注册页面上填写上必填的手机号、密码相关的用户信息。当用户提交时,先由页面判断是否符合提交的基础要求,符合要求则向服务器提交表单数据。如果填写不正确,就会弹出错误提示框,让用户重新输入。

注册模块如图3.2所示:

3.2 用户注册页面

3.3产品浏览

注册用户登录系统可以查看系统的产品的详细信息,如图3.3所示

3.3 产品详细信息界面

3.4 购物车管理

在该模块中,用户必须注册成为会员才可以在网站进行订购,未注册的用户或注册失败的会员只可以浏览物品,不可以把商品添加到购物车中。在购物车中,用户可以输入购买商品的数量,也可以删除购物车中的商品。

3.4 购物车管理

购物车controller层代码:

@RequestMapping("addCart")

@ResponseBody

public String addToCart(Integer goodsId,Integer num,HttpServletRequest request){

HttpSession session = request.getSession();

Users user=(Users) session.getAttribute("user");

Cart cart = cartService.findCartByUserId(user.getUserId(), goodsId);

if(cart!=null){

cart.setCartNum(cart.getCartNum()+num);

cartService.updateCart(cart);

}else{

Goods goods = goodsService.findById(goodsId);

Cart c=new Cart(goods, num, goods.getGoodsPrice(), user);

cartService.addGoodsToCart(c);

}

return "success";

}

@RequestMapping("findCartByUser")

@ResponseBody

public List<Cart> findCartByUser(HttpServletRequest request){

HttpSession session = request.getSession();

Users user=(Users) session.getAttribute("user");

List<Cart> list = cartService.findCartByUserId(user.getUserId());

return list;

}

@RequestMapping("deleteCart")

@ResponseBody

public String deleteCart(Integer cartId){

Integer rs = cartService.deleteCart(cartId);

if(rs>0){

return "success";

}else{

return "fail";

}

}

@RequestMapping("reduceCartNum")

@ResponseBody

public String reduceCartNum(Integer cartId){

Cart cart = cartService.findCartById(cartId);

cart.setCartNum(cart.getCartNum()-1);

Integer rs = cartService.updateCart(cart);

if(rs>0){

return "success";

}else{

return "fail";

}

}

@RequestMapping("addCartNum")

@ResponseBody

public String addCartNum(Integer cartId){

Cart cart = cartService.findCartById(cartId);

cart.setCartNum(cart.getCartNum()+1);

Integer rs = cartService.updateCart(cart);

if(rs>0){

return "success";

}else{

return "fail";

}

}

3.5 账户安全

在该模块中,只有注册并登录成功后的用户才能进入。在该模块中,用户可以修改登录密码。

3.5 账户安全界面

3.6 后台欢迎界面

在这个界面可以查看商城的总订单量,待发货数量,销售额,手机销售排行,热门商品浏览量等等。

欢迎界面前端代码:

<body style="background-color:#F2F2F2;padding-top:15px;padding-left:15px;padding-bottom:0px;">

<div class="layui-card" style="width: 480px; height: 250px;float:left;">

<div class="layui-card-header">待办事件</div>

<div class="layui-card-body" id="todo" style="width: 440px; height: 120px;">

<div class="layadmin-backlog" lay-anim="" lay-indicator="inside" lay-arrow="none" style="width: 100%; height: 80px;">

<li class="layui-col-xs6">

<a class="layadmin-backlog-body">

<h3>总订单量</h3>

<p><cite style="line-height:45px;" id="totalOrder"></cite></p>

</a>

</li>

<li class="layui-col-xs6">

<a class="layadmin-backlog-body">

<h3>待发货</h3>

<p><cite style="line-height:45px;" id="toDoOrder"></cite></p>

</a>

</li>

</div>

</div>

</div>

<div class="layui-card" style="width: 600px; height: 250px;float:left;margin-left:15px;">

<div class="layui-card-header">热门商品浏览量</div>

<div class="layui-card-body" id="hot" style="width: 560px; height:180px;"></div>

</div>

<div class="layui-card" style="width: 480px; height: 310px;float:left;">

<div class="layui-card-header">销售额及订单量趋势</div>

<div class="layui-card-body" id="order" style="width: 480px; height: 260px;"></div>

</div>

<div class="layui-card" style="width: 600px; height: 310px;float:left;margin-left:15px;">

<div class="layui-card-header">手机销量排行</div>

<div class="layui-card-body" id="volume" style="width: 580px; height: 260px;"></div>

</div>

</body>

<script type="text/javascript">

// 基于准备好的dom,初始化echarts实例

$(function(){

showToDo();

var myChart = echarts.init(document.getElementById('volume'),'wonderland');

var orderChart = echarts.init(document.getElementById('order'),'wonderland');

var hotChart = echarts.init(document.getElementById('hot'),'wonderland');

var layer;

layui.use('layer',function(){

layer=layui.layer;

});

// 指定图表的配置项和数据

myChart.setOption({

tooltip: {},

legend: {

},

xAxis: {

data: [],

axisLabel:{

interval:0//横轴信息全部显示

}

},

yAxis: {},

series: [{

type: 'bar',

data: []

}]

});

orderChart.setOption({

tooltip: {

trigger: 'axis'

},

//图例名

legend: {

data:['销售额','订单量']

},

//工具框,可以选择

toolbox: {

},

//x轴信息样式

xAxis: {

type: 'category',

boundaryGap: false,

data: [],

axisLabel:{

interval:0

},

},

yAxis : [

{

type : 'value'

}

],

series: [

//虚线

{

name:'订单量',

type:'line',

symbolSize:4,   //拐点圆的大小

data:[],

smooth:false,   //关键点,为true是不支持虚线的,实线就用true

itemStyle:{

normal:{

lineStyle:{

width:4,

type:'dotted'  //'dotted'虚线 'solid'实线

}

}

}

},

//实线

{

name:'销售额',

type:'line',

symbol:'circle',

symbolSize:4,

data:[]

}

]

});

hotChart.setOption({

title: {

text: '热门商品浏览量',//展示收藏表中,所有用户收藏的商品的总浏览量

x:'center'

},

tooltip: {

trigger: 'item',

formatter: "{a} <br/>{b} : {c} ({d}%)"

},

legend: {

orient: 'vertical',

x: 'left',

data: []

},

toolbox: {

show: true,

feature: {

mark: { show: true },

magicType: {

show: true,

type: ['pie', 'funnel'],

option: {

funnel: {

x: '25%',

width: '50%',

funnelAlign: 'left',

max: 1548

}

}

},

restore: { show: true }

}

},

series: [{

type: 'pie',

name:"浏览量",

radius: '55%',

center: ['50%', '60%'],

data: []

}]

});

myChart.showLoading();

$.ajax({

type:"post",

url:"goods/findGoodsByVolume",

dataType:"json",

success:function(res){

myChart.hideLoading();    //隐藏加载动画

myChart.setOption({        //加载数据图表

xAxis: {

data: res.name

},

series: [{

type: 'bar',

data: res.volume

}]

});

},

error:function(){

layer.msg("图表数据请求失败!",{icon:5,anim:6,time:1000});

myChart.hideLoading();

}

});

$.ajax({

type:"post",

url:"order/findTotalOrder",//查询销售额及订单量趋势

dataType:"json",

success:function(res){

orderChart.setOption({        //加载数据图表

xAxis: {

data: res.month

},

series: [{

name:'订单量',

type:'line',

data:res.sheets

},

{

name:'销售额',

type:'line',

symbol:'circle',

data:res.total

}

]

});

}

});

var names = [];

var brower = [];

$.ajax({

type:"post",

url:"guess/findMostHotGoods",//找热门商品

dataType:"json",

success:function(res){

$.each(res, function (index, item) {

names.push(item.name);    //挨个取出类别并填入类别数组

brower.push({

name: item.name,

value: item.num

});

});

hotChart.setOption({        //加载数据图表

legend: {

data: names

},

series: [{

data: brower

}]

});

}

});

});

//代办事项

function showToDo(){

$.ajax({

type:"post",

url:"order/findToDo",

dataType:"json",

success:function(data){

$("#totalOrder").html(data.total);

$("#toDoOrder").html(data.deliver);

}

});

}

</script>

3.7 查看订单

可以通过订单编号,订单状态查询订单。可以修改订单的状态,比如发货,删除,编辑订单。

订单部分前端代码:

<form class="layui-form">

<div class="layui-form-item" style="margin:15px;height:30px;">

<div style="height:40px;width:70px;float:left;line-height:40px;">订单编号:</div>

<input type="text" class="layui-input" style="width:250px;float:left;" id="orderIdKeyword" name="orderIdKeyword" value="" lay-verify="" placeholder="请输入订单编号" autocomplete="off">

<div style="height:40px;width:80px;float:left;line-height:40px;">  起始日期:</div>

<input type="text" id="startDate" name="startDate"  class="layui-input" style="float:left;width:100px;">

<div style="height:40px;width:80px;float:left;line-height:40px;">  结束日期:</div>

<input type="text" id="endDate" name="endDate"  class="layui-input" style="float:left;width:100px;">

<div style="height:40px;width:70px;float:left;line-height:40px;">  订单状态:</div>

<div class="layui-input-inline" style="width:150px;">

<select name="orderState" id="orderState">

<option value="">请选择订单状态</option>

<option value="1">待付款</option>

<option value="2">待发货</option>

<option value="3">待收货</option>

<option value="4">待评价</option>

<option value="5">完成</option>

</select>

</div>

<div class="layui-input-inline" style="width:80px;">

<a class="layui-btn" id="search" data-type="reload" name="search">

<i class="layui-icon"></i>搜索

</a>

</div>

<div class="layui-input-inline" style="width:80px;">

<button class="layui-btn layui-btn-normal" id="reset"  name="reset" type="reset">

<i class="layui-icon"></i>重置

</button>

</div>

</div>

</form>

<div>

<table id="orders" lay-filter="orders"></table>

</div>

<div id="formData" style="display:none;width:750px;padding-top:10px;">

<form id="orderForm" class="layui-form">

<div class="layui-form-item">

<label class="layui-form-label">订单编号</label>

<div class="layui-input-block">

<input type="text" name="orderId" id="orderId" style='background-color:#F8F8F8;' readonly="readonly" required lay-verify="required" value="" class="layui-input" />

</div>

</div>

<div class="layui-form-item">

<label class="layui-form-label">订单总价</label>

<div class="layui-input-block">

<input type="text" name="orderPrice" id="orderPrice" required lay-verify="required" value="" class="layui-input" />

</div>

</div>

<div class="layui-form-item">

<label class="layui-form-label">订单地址</label>

<div class="layui-input-block">

<input type="text" name="orderAddress" id="orderAddress" required lay-verify="required" value="" class="layui-input" />

</div>

</div>

<div class="layui-form-item">

<label class="layui-form-label">收货人</label>

<div class="layui-input-block">

<input type="text" name="orderUserName" id="orderUserName" required lay-verify="required" value="" class="layui-input" />

</div>

</div>

<div class="layui-form-item">

<label class="layui-form-label">收货电话</label>

<div class="layui-input-block">

<input type="text" name="orderPhone" id="orderPhone" required lay-verify="required" value="" class="layui-input" />

</div>

</div>

</form>

</div>

<script type="text/html" id="bar">

<a class="layui-btn layui-btn-xs" title="查看" lay-event="show">查看</a>

<a class="layui-btn layui-btn-xs layui-btn-normal" title="编辑" lay-event="edit">编辑</a>

<a class="layui-btn layui-btn-xs layui-btn-danger" title="刪除" lay-event="delete">刪除</a>

</script>

<script type="text/html" id="dateTpl">

{{ layui.laytpl.fn(d.editdate) }}

</script>

<script type="text/javascript">

var table;

var layer;

var form;

var upload;

var laydate;

var element;

layui.use(['layer', 'table','form','upload','laydate','element'], function ()

{

table = layui.table;

layer = layui.layer;

form =layui.form;

upload=layui.upload;

laydate=layui.laydate;

element=layui.element;

layui.laytpl.fn = function (value)

{

//json日期格式转换为正常格式

var date = new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));

var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;

var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();

return date.getFullYear() + "-" + month + "-" + day;

}

var start=laydate.render({

elem: '#startDate', //指定元素

type: 'date',

max: 'date',

btns:['clear','confirm'],

done:function(value,date){

endMax=end.config.max;

end.config.min=date;

end.config.min.month=date.month-1;

}

});

var end=laydate.render({

elem: '#endDate', //指定元素

type:'date',

max:'date',

done:function(value,date){

if($.trim(value)==''){

var curDate=new Date();

date={'date':curDate.getDate(),'month':curDate.getMonth()+1,'year':curDate.getFullYear()};

}

start.config.max=date;

start.config.max.month=date.month-1;

}

});

//--------------方法渲染TABLE----------------

var tableIns = table.render({

elem: '#orders'

, id: 'orders'

, url: 'order/findOrderBySplitPage'

,width:1140

, cols: [[

{ field: 'orderId', title: '订单编号', width: 300, align: 'center' }

, { field: 'orderUser', title: '下单用户', width: 120, align: 'center',templet:function(d){

return d.orderUser.userName

}

}

, { field: 'orderDate', title: '下单日期', width: 120, align: 'center' }

, { field: 'orderPrice', title: '订单总价', width: 120, align: 'center' }

,{field:'orderState', title: '订单状态', width: 102, align: 'center',templet: function(d){

if(d.orderState==1){

return "待付款";

}else if(d.orderState==2){

return "待发货";

}else if(d.orderState==3){

return "待收货";

}else if(d.orderState==4){

return "待评价";

}else{

return "完成";

}

}

}, {field:'orderExpressNo', title: '快递单号', width: 180, align: 'center',templet: function(d){

if(d.orderState==1){

return "等待付款";

}else if(d.orderState==2){

return "<button οnclick='deliverOrder(\""+d.orderId+"\")' class='layui-btn layui-btn-sm layui-btn-fluid layui-btn-warm'>发货</button>";

}else if(d.orderState==3){

return d.orderExpressNo;

}else if(d.orderState==4){

return d.orderExpressNo;

}else{

return d.orderExpressNo;

}

}

}, {title: '操作', fixed: 'right', width: 190, align: 'center', toolbar: '#bar'}

]]

, page: true

, limits: [5, 10, 15]

, limit: 10 //默认采用10

, done: function (res, curr, count)

{

//如果是异步请求数据方式,res即为你接口返回的信息。

//如果是直接赋值的方式,res即为:{data: [], count: 99} data为当前页数据、count为数据总长度

//console.log(res);

//得到当前页码

//console.log(curr);

$("#curPageIndex").val(curr);

//得到数据总量

//console.log(count);

}

});

//#region --------------搜索----------------

$("#search").click(function ()

{

var keyword=$("#orderIdKeyword").val();

var start=$("#startDate").val();

var end=$("#endDate").val();

var state=$("#orderState").val();

tableIns.reload({

where: {

orderIdKeyword: keyword,

startDate:start,

endDate:end,

orderState:state

},page: {

curr: 1 //重新从第 1 页开始

}

});

});

//#endregion

//工具条事件监听

table.on('tool(orders)', function (obj)

{ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"

var data = obj.data; //获得当前行数据

var layEvent = obj.event; //获得 lay-event 对应的值

var tr = obj.tr; //获得当前行 tr 的DOM对象

if (layEvent === 'edit')

{ //编辑

layer.open({

type: 1,

title: '编辑订单信息',

shade: 0.4,  //阴影度

fix: false,

shadeClose: true,

maxmin: false,

area: ['800px;', '400px;'],    //窗体大小(宽,高)

content: $('#formData'),

success: function (layero, index)

{

var body = layer.getChildFrame('body', index); //得到子页面层的BODY

$("#orderId").val(data.orderId);

$("#orderPrice").val(data.orderPrice);

$("#goodsPrice").val(data.goodsPrice);

$("#orderUserName").val(data.orderUserName);

$("#orderPhone").val(data.orderPhone);

$("#orderAddress").val(data.orderAddress);

form.render();

body.find('#hidValue').val(index); //将本层的窗口索引传给子页面层的hidValue中

},

btn:['修改','取消'],

yes: function(index, layero){

$.post('order/updateOrder',$('#orderForm').serialize(),function(data){

if (data == 'success')

{

parent.layer.msg('修改成功', { icon: 1, shade: 0.4, time: 1000 });

$("#search").click();

$("#handle_status").val('');

}

else

{

parent.layer.msg('修改失败', { icon: 5, shade: 0.4, time: 1000 });

}

layer.close(index);

});

}

});

}else if(layEvent === 'delete'){

layer.confirm('是否删除该订单?', {

btn: ['确认', '取消'] //可以无限个按钮

,btn1: function(index, layero){

$.ajax({

type: "POST",

url: "order/deleteOrder",

data: "orderId="+data.orderId,

success: function(msg){

if(msg=='success'){

parent.layer.msg('删除成功', { icon: 1, shade: 0.4, time: 1000 });

}else{

parent.layer.msg('删除失败', { icon: 5, shade: 0.4, time: 1000 });

}

}

});

$(tr).remove();

layer.close(index);

}

});

}else if(layEvent ==='show'){

var str="";

$.ajax({

type : "post",

url : "order/findOrderById",

async: false,

data:"orderId="+data.orderId,

dataType : "json",

success : function(data) {

str = str+ "<div class='layui-collapse' lay-accordion=''>";

var date=new Date(data.orderDate).toLocaleString();

str = str

+ "<div class='layui-colla-item'>"

+ "<h2 class='layui-colla-title'>订单编号:"

+ data.orderId

+ "  总价:"

+ data.orderPrice

+ "元 订单日期:"+date+"</h2>"

+ "<div class='layui-colla-content layui-show'><h4>收货人:"

+ data.orderUserName

+ "  收货地址:"

+ data.orderAddress

+ " 电话:"+data.orderPhone+"</h4>"

+ "<div class='layui-form'><table class='layui-table'><thead><tr><th>商品名称</th><th>价格</th><th>数量</th><th>小计</th></tr>"

+ "</thead><tbody>";

var arr = data.detailList;

for (var t = 0; t < arr.length; t++) {

str = str

+ "<tr><td><a href='goods/detail?goodsId="

+ arr[t].detailGoods.goodsId

+ "'>"

+ arr[t].detailGoods.goodsName

+ "</a></td>" + "<td>"

+ arr[t].detailGoods.goodsPrice

+ "</td><td>"

+ arr[t].detailNum

+ "台</td><td>"

+ arr[t].detailGoods.goodsPrice

* arr[t].detailNum + "元</td>"

+ "</tr>";

}

str = str

+ "</tbody></table></div>"

+ "</div></div>";

str = str + "</div>";

}

});

layer.open({

type: 1,

title: '查看订单详情',

shade: 0.4,  //阴影度

fix: false,

shadeClose: true,

maxmin: false,

area: ['800px;', '400px;'],    //窗体大小(宽,高)

content: str,

success: function (layero, index)

{

var body = layer.getChildFrame('body', index); //得到子页面层的BODY

element.render();

body.find('#hidValue').val(index); //将本层的窗口索引传给子页面层的hidValue中

},

btn:['关闭'],

yes: function(index, layero){

layer.close(index);

}

});

}

});

});

function deliverOrder(id){

layer.open({

type: 1,

title: '发货',

shade: 0.4,  //阴影度

fix: false,

shadeClose: true,

maxmin: false,

area: ['600px;', '250px;'],    //窗体大小(宽,高)

content: "<div style='width:500px;padding-top:15px;'><div class='layui-form-item'><label class='layui-form-label'>订单编号</label>"+

"<div class='layui-input-block'><input type='text' name='orderId' id='orderId' style='background-color:#F8F8F8;' "+

" readonly='readonly' required lay-verify='required' value='"+id+"' class='layui-input' /></div></div>"+

"<div class='layui-form-item'><label class='layui-form-label'>快递单号</label><div class='layui-input-block'><input type='text' "+

" id='expressNo' required lay-verify='required' class='layui-input' /></div></div></div>",

success: function (layero, index)

{

var body = layer.getChildFrame('body', index); //得到子页面层的BODY

body.find('#hidValue').val(index); //将本层的窗口索引传给子页面层的hidValue中

},

btn:['发货','取消'],

yes: function(index, layero){

var no=$("#expressNo").val();

$.post('order/deliverOrder',{orderId:id,expressNo:no},function(msg){

if (msg == 'success')

{

parent.layer.msg('发货成功', { icon: 1, shade: 0.4, time: 1000 });

$("#search").click();

$("#handle_status").val('');

}

else

{

parent.layer.msg('发货失败', { icon: 5, shade: 0.4, time: 1000 });

}

layer.close(index);

});

}

});

}

</script>

3.8 用户管理

描述:管理员点击左侧的菜单“用户管理”,页面跳转到用户信息管理界面,从数据库中查询出所有的用户信息,并把这些信息显示到页面中。主要包括用户名、类型信息。点击删除按钮实现用户信息的删除操作。如图3.6所示。

3.6 用户管理界面

4 系统测试

在设计系统和系统开发的过程中,我们常常会遇到一些错误,有时是一些简单的语法错误,对于语句的语法错误,我们再编码的时候很多的开发工具就能够识别出来从而很容易发现并改正;还有一些错误是很难发现的,开发工具也不会给出提示,只有在我们运行程序是才会报错,这就需要我们对程序进行调试,如果遇到这种错误我们可以通过加断点或者打印语句等方法来定位错误,再根据错误信息改正错误。

系统开发完成后,测试环节是必不可少的。系统在开发过程中,首先分析需求和设计阶段得出的结论,用来确定测试的目的和范围。系统测试有单元测试、集成测试和系统测试等。

4.1 测试方法

本系统采用黑盒测试法,黑盒测试又称为功能测试。黑盒测试不同于白盒测试,不需要测试人员具有专业的测试知识,也不需要了解系统的内部运行细节。在测试时只需要找到所有输出功能和输入的集合,对每个模块分别进行测试分析。白盒测试,需要测试人员具有一定的专业知识,要懂得系统的内部工作过程。

4.2 测试环境介绍

测试环境:操作系统win10系统,数据库MYSQL。

测试数据:用户登录。

4.3 功能模块测试

用户登录测试,测试结果如图4.3.1所示。

表4.3.1

用例名称

用户登录

测试时间

5.10

对应需求

用户登录

测试人员

功能描述

验证用户登录

测试目的

不存在用户或者帐号密码错误登录是否成功

前置条件

数据库中存在用户(帐号:undo,密码:123456)

非法用户(undoo)

测试步骤

1.在登录界面中输入帐号和密码

2.单击“登录”按钮

序号

输入数据/动作

预期结果

实际结果

1

输入用户名和密码

去服务器数据库验证

和预期结果一致

2

输入非法用户

提示登录错误信息

和预期结果一致

在进行用户登录测试时,输入用户名和密码,点击登录按钮后,系统会去后台对用户名和密码进行校验。如果用户名和密码正确则跳转到用户信息界面,如果用户名和密码不正确就会显示登录不成功弹出提示框显示登录失败。测试效果如图4.3.2所示。

图4.3.2

5 收获与体会

网上手机商城购物系统采用了Java的SSM框架搭建。迫于用户的需求系统对此进行了充分的分析,在测试之后,运行的结果也达到了所期望的要求,为了能够使系统更加的人性化,导航条实现了对商品的分类功能。用户可以快速的对所有商品进行查看。

鉴于本人在知识量、开发经历等都处于初学阶段,系统可能在某些地方仍有bug。比如在一些具体的功能分析上考虑的还不够周到,导致系统在实现过程中不够详细、具体,所以在今后的学习过程里我会更加努力。

致谢

本论文及其中所载研究成果是在我的导师赵黎老师的悉心指导和帮助下完成的,从最初论文选题,到框架设计,直至定稿,老师都倾注了大量心血。老师深厚的理论素养,丰富的实践知识,开拓了我的视野,使我的开发能力有了很大的提高。此外,老师严谨的治学态度和科学的工作方法更是给予了我极大的帮助,并且必将对我今后的工作和生活产生极为深远的影响,在此衷心感谢赵黎老师对我学习、生活及科研方面的关心与指导。

参考文献

[1] 杨开振等. Java EE互联网轻量级框架整合开发— —SSM框架spring和Redis实现[M]. 北京:电子工业出版,2017.

[2]李俊民. HTML 5+CSS 3网页设计经典范例[M].北京:电子工业出版,2010.

[3]邹红霆. 基于SSM框架的Web系统研究与应用[J]. 湖南理工学院学报(自科版), 2017,30(1):39-43.

[4]程杰. 大话设计模式[M]   北京:清华大学出版社,2010

[5]郭航宇,成丽君. 基于javaEE的诗词文化网站系统设计与实现[J]. 电子技术与软件工程,2018(11):7-8.

[6] 杨黎薇. 基于JavaEE设计模式的烈度速报建设与应用[J]. 世界地震工程,2018,34(02):147-156.

[7] 牛勇超. 基于JavaEE的开放实验管理系统的设计与实现[J]. 实验技术与管理,2017,34(01):153-156.

[8]韩姗姗. 面向复杂学习的高校计算机实践类教材建设[J]. 计算机教育,2017(03):57-60.

[9] 张晓刚. 项目进阶驱动的JavaEE课程实践教学改革探索[J]. 计算机教育,2016(09):115-118.

[10] 王小正,杨鑫,侯青. 面向应用型本科院校的JavaEE教材建设[J]. 计算机教育,2015(12):98-101.

[11] 黄统奎,张艳红. 基于JavaEE高校毕业设计管理系统的设计与实现[J]. 电脑知识与技术,2014,10(19):4384-4386.

[12] 王荣芝,周洪翠,于世华. 基于Android+JavaEE技术的旅游助手系统设计与实现[J]. 电子技术与软件工程,2014(19):64-65.

[13]. 翟悦,王立娟. 基于CDIO模式的JavaEE课程改革方案研究[J]. 电脑知识与技术,2015,11(19):140-141.

[14]朱敏,朱晴婷,李媛媛编著. JSP Web应用教程[M].北京:清华大学出版社,2018

[15]陶林峰. 基于J2EE的网上商城的设计与实现[D] ,2015.

附录

@RequestMapping("findAll")

public String findAllGoods(Model model){

List<Goods> list = goodsService.findAll();

model.addAttribute("goodsList", list);

return "list";

}

@RequestMapping("{goodsId}")

public String findAllGoods(@PathVariable("goodsId")Integer goodsId,Model model){

Goods goods = goodsService.findById(goodsId);

List<Evaluate> evaList = evaluateService.findEvaluateByGoodsId(goodsId);

model.addAttribute("goods", goods);

model.addAttribute("evaList", evaList);

return "detail";

}

@RequestMapping("preUpdate")

public String preUpdate(Integer goodsId,Model model){

Goods goods = goodsService.findById(goodsId);

model.addAttribute("goods", goods);

return "update";

}

@RequestMapping("findBySplitPage")

@ResponseBody

public JSONObject findBySplitPage(Integer page,Integer limit,String keyword){

PageInfo<Goods> info = goodsService.findBySplitPage(page, limit,keyword);

JSONObject obj=new JSONObject();

obj.put("msg", "");

obj.put("code", 0);

obj.put("count", info.getTotal());

obj.put("data", info.getList());

return obj;

}

@RequestMapping("findGoodsByType")

@ResponseBody

public List<Goods> findGoodsByType(Integer typeId){

List<Goods> list = goodsService.findGoodsByType(typeId);

return list;

}

@RequestMapping("detail")

public String findGoodsDetail(Integer goodsId,Model model,HttpServletRequest request){

Goods goods = goodsService.findById(goodsId);

model.addAttribute("goods",goods);

model.addAttribute("evaList", goods.getEvaList());

HttpSession session = request.getSession();

Users user=(Users) session.getAttribute("user");

if(user!=null){

Guess guess = guessService.findGuessByUserId(user.getUserId(), goods.getGoodsId());

if(guess!=null){

guess.setGuessNum(guess.getGuessNum()+1);

guessService.updateGuess(guess);

}else{

Guess g=new Guess(goods, 1, -1, user);

guessService.addGuess(g);

}

}

return "userview/product_detail";

}

@RequestMapping("findHotGoods")

@ResponseBody

public List<Goods> findHotGoods(){

return goodsService.findHotGoods(4);

}

@RequestMapping("search")

public ModelAndView searchGoodsByName(String keyWord){

ModelAndView mv=new ModelAndView();

List<Goods> list = goodsService.findGoodsLikeName(keyWord);

mv.addObject("searchList",list);

mv.setViewName("userview/search");

return mv;

}

@RequestMapping("searchPre")

@ResponseBody

public List<Goods> searchPreGoods(String keyword){

List<Goods> list = goodsService.findGoodsLikeName(keyword);

return list;

}

@RequestMapping("delete")

@ResponseBody

public String deleteGoods(Integer goodsId){

Integer rs = goodsService.deleteGoods(goodsId);

if(rs>0){

return "success";

}else{

return "fail";

}

}

@RequestMapping("updateGoods")

@ResponseBody

public String updateGoods(Goods goods){

Integer rs = goodsService.update(goods);

if(rs>0){

return "success";

}else{

return "fail";

}

}

@RequestMapping("batchDelete")

@ResponseBody

public String batchDelete(String batchId){

Integer rs=0;

String[] id = batchId.split(",");

for (String s : id) {

Integer goodsId = Integer.valueOf(s);

rs = goodsService.deleteGoods(goodsId);

}

if(rs>0){

return "success";

}else{

return "fail";

}

}

//下订单

@RequestMapping("takeOrder")

public String takeOrder(Integer[] goodslist,Integer addr,Model model,HttpServletRequest request){

List<Cart> cartList=new ArrayList<Cart>();

List<OrderDetail> detailList=new ArrayList<OrderDetail>();

Double totalPrice=0D;

for (Integer i : goodslist) {

Cart cart = cartService.findCartById(i);

totalPrice+=cart.getCartNum()*cart.getCartGoods().getGoodsPrice();

cartList.add(cart);

OrderDetail detail=new OrderDetail(cart.getCartGoods(), cart.getCartGoods().getGoodsPrice()*cart.getCartNum(), cart.getCartNum());

detailList.add(detail);

}

HttpSession session = request.getSession();

Users user=(Users) session.getAttribute("user");

Date orderDate=new Date();

Address address = addressService.findAddresById(addr);

String a=address.getAddrProvince()+address.getAddrCity()+address.getAddrArea()+address.getAddrDetail();

Order order=new Order(user, orderDate, totalPrice, 1, address.getAddrNickname(), address.getAddrPhone(), a);

order.setDetailList(detailList);

Order takeOrder = orderService.takeOrder(order);

for (Cart c : cartList) {

Goods goods = goodsService.findById(c.getCartGoods().getGoodsId());

goods.setGoodsNum(goods.getGoodsNum()-c.getCartNum());

goods.setGoodsVolume(goods.getGoodsVolume()+c.getCartNum());

goodsService.update(goods);

cartService.deleteCart(c.getCartId());

}

model.addAttribute("order",takeOrder);

List<Guess> guessList = guessService.findGuessGoodsByUserId(user.getUserId(), 4);

model.addAttribute("guessList", guessList);

return "userview/takeorder";

}

@RequestMapping("findReadPayOrder")

@ResponseBody

public List<Order> findReadyPayOrder(HttpServletRequest request){

HttpSession session = request.getSession();

Users user=(Users) session.getAttribute("user");

List<Order> orderList = orderService.findOrdersByUserIdAndState(user.getUserId(), 1);

return orderList;

}

@RequestMapping("findReadyToDeliverOrder")

@ResponseBody

public List<Order> findReadyToDeliverOrder(HttpServletRequest request){

HttpSession session = request.getSession();

Users user = (Users) session.getAttribute("user");

List<Order> orderList = orderService.findOrdersByUserIdAndState(user.getUserId(), 2);

return orderList;

}

@RequestMapping("findReadyToReceiveOrder")

@ResponseBody

public List<Order> findReadToReceiveOrder(HttpServletRequest request){

HttpSession session = request.getSession();

Users user = (Users) session.getAttribute("user");

List<Order> orderList = orderService.findOrdersByUserIdAndState(user.getUserId(), 3);

return orderList;

}

@RequestMapping("findReadyToEvaluateOrder")

@ResponseBody

public List<Order> findReadyToEvaluateOrder(HttpServletRequest request){

HttpSession session = request.getSession();

Users user = (Users) session.getAttribute("user");

List<Order> orderList = orderService.findOrdersByUserIdAndState(user.getUserId(), 4);

return orderList;

}

@RequestMapping("findFinishOrder")

@ResponseBody

public List<Order> findFinishOrder(HttpServletRequest request){

HttpSession session = request.getSession();

Users user = (Users) session.getAttribute("user");

List<Order> orderList = orderService.findOrdersByUserIdAndState(user.getUserId(), 5);

return orderList;

}

旅游管理系统-JAVA【数据库设计、源码、开题报告】相关推荐

  1. python爬虫框架论文开题报告范文_仿今日头条新闻爬虫设计毕业论文+设计源码+开题报告...

    摘要 随着社会日新月异和互联网进入大数据时代,自媒体得到了迅猛的发展,人们获取新闻资讯的方式越来越多,接触和使用新闻信息的方式正在逐渐改变,受众从被动接受信息到按需主动搜索信息,而新闻的种类繁多杂乱, ...

  2. 基于ssm的校园门户网站源码+开题报告+需求分析+mysql数据库+前端html文件

    下载地址:https://download.csdn.net/download/biyesheji250/28740242 项目介绍: 基于ssm的校园门户网站源码+开题报告+需求分析+mysql数据 ...

  3. jsp ssm289美食推荐管理系统 java毕业设计项目源码含论文ppt介绍

    一.源码描述   这是新款的javassm毕业设计项目源码,开发工具:idea,也支持eclipse,数据库:MySQL功能也比较全面,比较适合作为毕业设计使用 二.功能介绍 美食推荐管理系统的主要使 ...

  4. 客栈管理系统java源代码_源码客栈项目源码分类规则

    源码客栈团队截至目前已经为Java相关课程设计.实训.毕业设计开发了很多对应的源码,为了整理这些源码我们制定了如下的分类规则,方便大家迅速定位找到合适自己的源码. 星星等级:✩✩星星数量表示难易程度, ...

  5. 基于Android的人事管理系统开发与设计源码(一)

    基于Android开发的人事管理系统 链接:https://blog.csdn.net/yql_617540298/article/details/108553842 上面的链接详细的介绍整个项目,是 ...

  6. 计算机毕业设计源码分享双鱼林,双鱼林SSM图书信息管理系统毕业课程设计源码 - WEB源码|源代码 - 源码中国...

    双鱼林SSM图书信息管理系统\.classpath 双鱼林SSM图书信息管理系统\.mymetadata 双鱼林SSM图书信息管理系统\.project 双鱼林SSM图书信息管理系统\.setting ...

  7. android短彩信数据库设计源码解析(二)

    转载请注明出处:http://blog.csdn.net/droyon/article/details/8734167 这几天连续加班,昨天很早就睡了.一个人的时候要学会自我祝福,祝自己注意身体,天天 ...

  8. 新生报到小程序毕业设计,微信新生报到小程序系统设计与实现,微信小程序毕业设计论文怎么写毕设源码开题报告需求分析怎么做

    项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信小程序新生报到系统,前台用户使用小程序,后台管理使用基PHP+MySql的B/S架构:通过后台添加学校信息.分院信息.班级信息.老师信息 ...

  9. c语言编写闹钟主程序流程图,基于STC15W4K58S4单片机的电子万年历设计源码与报告(数码管显示)...

    基于STC15W4K58S4单片机的电子万年历(数码管显示)该压缩包包含源码TXT文件 源工程文件(Keil uVision4文件)和课程设计报告 电子时钟的设计 -单片机综合设计报告 目录 1  任 ...

  10. Java课程设计源码——学生信息管理系统 SQL

    2022.6.9 更新 这个课程作业的代码有小伙伴反馈有问题(数据库无法连接等),但博主最近学业不用Java了,暂时没时间看,如果有同学有解决方案,可以在下面评论帮助一下其他同学.实在抱歉啦. pac ...

最新文章

  1. Python初学者零碎基础笔记(一)
  2. 2017国二java题库,2017全国计算机二级考试JAVA考试题库
  3. AS编写sdk并打成jar包供其它APP调用
  4. 关于Cocos2d-x属性和引用
  5. h5 修改title 微信_微信公众号客服消息不限次数推送如何设置?
  6. HALCON示例程序novelty_detection_dyn_threshold.hdev纱网缺陷检测
  7. 低代码能做什么?这家服务商用钉钉宜搭打造了智慧医院管理应用
  8. vue v2.5.0源码-双向数据绑定
  9. linux 下软READ 的使用和参数 以及 实现虚拟READ步骤
  10. windows2003手工安装配置php5详细指南
  11. Vue开发腾讯地图坐标拾取器
  12. 使用Notification实现站内信
  13. 北京语言大学计算机英语统考,大学英语b级复习资料_统考英语b题库|北语网院大学英语b辅导...
  14. vmlinuz文件解压缩
  15. SoueceTree 本地仓库和贮藏两种方式冲突解决
  16. 58同城2021秋招数据分析笔试
  17. vb限制文本框输入内容长度_限制VB文本框输入的代码
  18. php升降调_音乐剪辑 合并 伴奏升降调等等 伴奏升降调软件下载
  19. 计算机仿真课程设计题目,《运动控制系统》课程设计题目
  20. unreal 顶点法线与 面法线

热门文章

  1. 拍卖系统业务演进过程(一)
  2. 侯震老师--沪师经纪
  3. AcWing 844. 走迷宫(迷宫问题+最短路径+BFS+最短路径输出)
  4. 从入门到精通之专家系统CLIPS(一)CLIPS初识与概述
  5. 微信多群直播助手功能介绍
  6. 蓝鹊生物国内首款新冠mRNA嵌合体疫苗获批临床
  7. 射频标签工作频率的分类
  8. Linux内核LED模块分析(二)
  9. 每天一个Java知识点(spring-计划任务)
  10. “Word在试图打开文件时遇到错误。请尝试下列方法:* 检查文档或驱动器的文件权限。* 确保有足够的内存和磁盘空间。* 用文件恢复转换器打开文件。”问题!...