第一章 绪论
1.1 选题背景和意义
随着旅游消费市场的不断扩大,人们的出行方式也由原来的团体旅游向个性化、碎片化的预订转变。这就会对旅行社的服务模式提出新的要求。传统的旅行社依靠线下门店咨询、电话预订、手工登记订单等方式进行运作,操作过程繁杂而且容易出现差错。游客面对多个旅游产品要分别联系不同的供应商,信息获取效率低。互联网技术向旅游行业渗透之后,各种OTA平台出现,但是大部分服务于大型旅行社或者酒店集团。中小型旅行社缺少专门的线上业务管理平台,不能很好地把自身的特色路线、合作酒店资源推向社会。彭诺等人[1]认为将Spring Boot和Vue.js融合在一起可以提高旅游信息整合能力。金晶晶[2]认为旅行社经营管理课程中案例实践具有非常重要的意义,说明业界对于旅行社业务流程信息化改造有着十分急迫的需求。丁文雅[3]从OBE理念出发,就旅行社经营管理人才的实践能力培养展开研究。创建一个专门为旅行社业务服务的网站,既可以满足游客一站式预订的需求,也可以为旅行社提供订单管理、客户跟踪、售后处理等一系列的数字化工具,具有很强的现实意义。该系统主要是对旅游产品预订全流程线上化进行改革,在整合景点、酒店和线路三种类型的基础上,创建起由信息展现到订单生成再到售后服务的全部流程闭环。
1.2 国内外研究现状
国内旅游信息化平台从最初的只是信息展示、交易闭环,逐渐发展成为现在更加细分化的垂直领域。早期的旅游网站主要是信息发布的平台,包含景点介绍、线路推荐等内容,不能进行线上交易。之后出现垂直旅游社区,用户生成内容成了主要的信息来源,游记攻略、点评打分等互动功能加强了用户的参与度,但是预订环节仍然需要跳转到第三方平台上进行操作。伴随着移动互联网的普及,专业旅游预订系统也不断发展壮大,各类APP将票务、酒店、交通等各种服务整合在一起,达到一站式购买的目的。刘秀实(2001)[4]认为虚拟仿真的平台可以用来对旅行社管理教学进行模拟,也可以用来提高流程效率。王慧元等人[5]认为项目驱动教学模式下,校企合作课程开发具有旅行社业务流程模块化特点。刘丽华等[6]认为旅行社管理课程改革要依靠学习体验评价来实现。李志伟[7]认为从职业素养的角度来开展旅行社管理课程思想政治教育的研究,突出业务规范与职业道德。这些研究从教育角度对旅行社业务流程中信息管理、客户服务、订单处理等各方面的标准要求进行了分析。
国外旅行社管理系统的兴起比我国早,其发展轨迹是先有社交平台后数据驱动。早期的系统主要是以行程分享、社区互动为主,用户之间交流出行的经验。随着大数据技术的成熟,系统开始收集用户的使用数据,并从中提取出用户喜好来进行个性化的推荐。成熟的旅行社管理软件已经把客户关系管理、供应链管理、财务结算等模块有机地整合在一起,形成起一个完整的业务中台。Zhang Y[8]认为国外对于应用型本科院校旅行社管理课程教学改革也十分重视,也非常重视业务流程的信息化模拟。Travelport[9]促使ADAC旅行社管理服务实现数字化转型,表现出技术对于传统业务流程的改造能力。Travel Booking System开发实践[10]展示了OTA软件从需求分析到系统实现的完整路径。Travelomatix[11]所提的B2C和B2B旅行社管理软件可以满足各类代理机构的需求。Chen X[12]对旅游发展背景下高校旅行社管理课程教学进行研究,分析了行业对于信息化人才的需求。由此可以看出,国外旅行社的管理系统已经由原来的单一功能向全流程覆盖发展。
1.3 研究内容
本文以旅行社网站设计与实现为中心任务开展工作。先做需求分析,确定普通用户、旅行社、管理员这三个角色的功能范围以及业务交互的关系,整理出旅游景点、酒店客房、旅游路线三个产品线的预订过程。在此基础上进行系统架构设计,采用前后端分离模式,后端用Spring Boot创建RESTful API,前端用Vue.js完成页面交互,数据库选择MySQL存储业务数据。功能实现阶段先开发用户端的预订模块和订单管理模块、旅行社端的团体订单和售后管理模块、管理员端的资源和订单监管模块。数据库设计符合规范化原则,对用户、产品、订单三个主要表之间的关系进行约束。本研究只对业务逻辑进行完整性检验和数据流转一致性检验,并未对支付网关对接、第三方地图API接入等附加内容进行检验。最终实现可以运行的Web系统原型、数据库设计文档和测试报告。系统开发采取面向对象的分析和设计办法,用敏捷迭代的方式分模块前进。
第二章 相关技术介绍
2.1 Spring Boot框架
该框架是Spring生态系统对于配置复杂性进行简化的需求而产生的。传统的Spring应用要编写的XML配置较多,项目的建立成本也比较高。Spring Boot用自动配置来降低项目的初始化门槛,开发者只需要添加相应的依赖就可以得到默认的配置。框架在运行的时候会扫描类路径下所有存在的依赖库,然后依据这些依赖库的存在情况来决定是否开启某些功能。技术结构由启动器模块、自动配置模块、执行器模块等逻辑单元组成,各个单元之间用条件注解进行装配控制。当系统要对旅行社网站的HTTP请求进行处理的时候,Spring Boot所给的嵌入式Servlet容器就会接收并转发这些请求[13]。当请求到达控制器之后,框架就会解析请求参数,然后执行对应业务处理逻辑。处理完成之后,框架就会把结果数据转成JSON格式返回给客户端。该框架可以对数据源进行配置,可以对事务进行管理,可以实现缓存的抽象。在旅行社网站项目中,用户提交的门票预订请求被Controller接收之后,就会被Service层进行业务校验,最后通过数据访问层持久化到数据库。
2.2 Vue.js框架
Vue.js是渐进式框架,主要用来构建用户界面,它的核心库只关注视图层。该框架响应式的数据绑定机制,可以让开发者用声明式的方式把DOM和底层数据联系起来。数据一旦发生改变,框架就会自动追踪到所依赖的其它元素,并且重新渲染这些元素相关的部分。技术结构由模板编译系统、响应式系统、虚拟DOM系统等各个子系统组成。模板系统把声明式的模板转成渲染函数,响应式系统借助劫持数据属性的读写操作来获取依赖关系。虚拟DOM机制在每次渲染的时候创建新的旧节点树进行比较,计算出最小化更新的操作并应用到实际的DOM上。在旅行社网站页面渲染的时候,当用户浏览景点列表的时候,Vue.js就会根据数据数组动态创建对应的DOM元素[14]。当用户对筛选条件进行修改的时候,就会使组件内部的computed属性发生改变,并且视图部分也会随之更新。该框架可以实现组件化的开发方式,每一个Vue组件都是一个独立的模板、逻辑和样式文件。
2.3 MySQL数据库
MySQL属于一种关系型数据库管理系统,它有着诸多的存储引擎,这些引擎可以用于存储各种类型的数字信息。InnoDB引擎有事务处理功能,用行级锁来控制并发访问。数据在物理上是以表空间文件的形式存储的,逻辑上是由数据库、表、字段、索引等对象组成的。当执行查询的时候,MySQL的查询优化器会根据统计信息来决定使用哪个索引进行访问。该系统提供主键索引、唯一索引、普通索引等类型的索引,并且索引可以提高数据检索的速度。旅行社网站的数据管理环境里,用户提交的订单信息要进行持久化的保存[15]。MySQL给订单表指定存放地点,创建唯一索引到订单编号上。多个用户一起预订同一个酒店的房间的时候,数据库依靠事务隔离机制来避免超卖的情况发生。此数据库也包含视图、存储过程以及触发器等项,可以对复杂的业务逻辑进行处理,放到数据库上执行。
2.4 MyBatis持久层框架
MyBatis是一个支持自定义SQL的持久层框架,它可以将java对象和sql语句进行映射。该框架的核心组件包括SqlSessionFactory、SqlSession、执行器、映射器等。SqlSessionFactory负责创建SqlSession实例,每个会话代表一次数据库连接。映射器文件中定义了SQL语句和Java方法之间的对应关系,参数映射机制把方法参数转换成SQL占位符的值。执行SQL的时候,MyBatis使用JDBC接口向数据库发出命令,结果集就会被自动包装成Java对象。在旅行社网站数据访问层中,景点查询功能要根据不同的类型筛选数据[16]。MyBatis的映射文件中使用动态SQL时,会根据传入的参数是否为空来判断是否添加条件语句。它还会提供一级缓存、二级缓存的功能来节省重复调用数据库所造成的耗电开销。关联查询场景下,MyBatis的结果映射功能可以把多表连接查询的结果集自动转化为嵌套的对象结构。
第三章 系统需求分析
3.1 可行性分析
3.1.1 技术可行性
基于Spring Boot框架开发后端服务,Spring Boot框架可以实现自动配置和依赖注入,把数据访问层和业务逻辑层很好地结合在一起。前端使用Vue.js框架做页面的组件化开发,采用HTTP协议同后端API达成数据交互。MySQL数据库可以做事务处理和索引优化来满足订单数据的一致性。使用IntelliJ IDEA集成开发环境,用Maven对项目进行构建以及依赖管理。以上所用到的技术栈都是开源成熟的方案,社区文档充足,在开发过程中遇到的技术问题可以参考文档解决。系统运行环境只需要JDK8以上版本以及MySQL5.7以上版本的实验室现有的设备就可以达到部署条件。
3.1.2 经济可行性
系统开发所需的软件工具均为开源或免费版本,包括IntelliJ IDEA社区版、MySQL Community Server、Navicat试用版等,无需购买商业许可证。硬件上使用个人计算机即可完成开发和测试工作,不需要购买专用的服务器设备。系统部署之后可以运行在云服务商提供的低成本云主机上,初期只需要单机配置就可以满足中小型旅行社的业务量。开发周期内的人力成本主要是指开发者投入的时间,而不包含外包费或者额外技术采购费。从系统建设经济性分析可知,系统建设投入合理,旅游线上业务开拓产生的经济效益大于投入成本。
3.1.3 操作可行性
系统分别对普通用户、旅行社工作人员、管理员这三类人设计独立的操作界面。普通用户用浏览器访问前端页面,景点查询、酒店浏览、订单提交等操作全部采用表单填写+按钮点击的方式,交互逻辑和常见的电商网站一致。旅行社工作人员登录之后就可以进入到自己的专属管理面板中,对团体订单的处理、行程状态的更新、售后的回复等操作都是采用列表式的形式呈现出来,并且会弹出编辑界面。管理员在配置资源的时候采用表格管理界面,可以对添加、修改、删除等功能有基本的操作权限。系统整体的操作流程简单明了,各个角色的用户只需要简单的指导就可以独立使用。
3.2 功能需求分析
3.2.1 普通用户角色功能需求
普通用户角色在系统中可以完成注册登录操作来获得系统使用的权限,可以浏览旅游景点、酒店信息、酒店客房、旅游路线等基础信息,可以发起门票、客房、路线的预定申请,可以查询自己的门票订单、客房订单、路线订单,并且可以对这些订单进行管理。普通用户角色用例图如图3-1所示。
图3-1普通用户用例图
3.2.2 旅行社角色功能需求
旅行社角色可以对系统里由普通用户产生的团体订单进行集中管理,统筹客户的整体行程安排,处理订单售后问题,对用户的留言反馈进行管理,并维护和合作方的相关数据信息。旅行社角色用例图如图3-2所示。
图3-2旅行社用例图
3.2.3 管理员角色功能需求
管理员角色除了具有旅行社角色的团体订单管理、客户行程管理、订单售后管理、合作数据管理的权限之外,在系统上管理景区类型、旅游点、酒店、旅游线路这些基础资源并且统一管理门票预定、门票订单、客房预定及路线预定等各种交易记录。管理员角色用例图如图3-3所示。

图3-3管理员用例图
第四章 系统设计
4.1 系统架构设计
系统用前后端分离的结构来组织用户界面和业务逻辑层。前端采用Vue.js单页面应用框架进行开发,主要负责页面渲染以及用户的交互操作。后端部分基于Spring Boot框架提供RESTful API,处理业务逻辑与数据持久化。前端使用Axios库向后端发送HTTP请求,后端返回的也是JSON格式的数据。在这样的架构模式之下,表现层与数据访问层被分离开来,前端侧重用户体验优化,后端侧重业务规则的执行。用户浏览器上运行的Vue应用发起请求,Spring Boot控制器收到请求后调用服务层的方法。服务层对数据进行校验、业务计算,用持久层框架MyBatis完成数据库操作。MySQL数据库存放用户的个人信息,产品的相关信息,订单的详细记录等业务数据。该架构可以实现前后端独立部署,并且能够同时进行开发工作[17]。系统架构图如图4-1所示。
图4-1系统架构图
4.2 功能结构设计
系统按照普通用户、旅行社、管理员三个不同的角色来提供不同的功能模块。普通用户模块包含旅游景点查看、酒店信息查看、酒店客房查看、旅游路线查看、门票预订、客房预订、路线预订、门票订单管理、客房订单管理、路线订单管理。旅行社模块有团队订单处理、客户行程安排、订单售后服务、留言评价处理、合作关系纪录整理的功能。管理员模块在旅行社模块的基础上增加了景点类型管理、旅游景点管理、门票预订管理、门票订单管理、酒店信息管理、客房订单管理、旅游路线管理、路线订单管理。该系统功能结构如图4-2所示。
图4-2系统功能结构图
4.3 业务流程设计
4.3.1 系统总体业务流程图设计
系统的总体业务流程是从用户登录开始的。用户输入凭证之后,系统会验证身份,根据所选角色类型,跳转到相应的工作区。普通用户进入前台页面后即可选择预订景区、宾馆或者路线。提交预订申请之后,系统会进行库存核验,审核通过之后生成待支付订单。用户完成支付之后订单状态就变成已确认。旅行社登录后台查看团体订单,更新订单接收状态并录入客户行程。管理员监控所有订单流转,对异常订单进行干预处理。系统总体业务流程如图4-3所示。

图4-3系统总体业务流程图
4.3.2 门票预订流程设计
用户进入门票预订模块之后选择目标景点。系统读取这个景点门票价格和库存信息。用户填写预订数量和联系人信息之后就提交了预订请求。系统检验预订单不许超出已有的库存量。校验通过之后生成门票预订记录,订单状态设为待确认。用户可以进入订单管理页面查看预订信息,并且完成后面的支付工作。门票预订流程如图4-4所示。

图4-4门票预订流程图
4.3.3 客房预订流程设计
用户在酒店客房列表里选取所选的房间。系统显示客房的全部信息和价格。根据用户输入的入住日、离店日自动生成入住天数和总价。用户预订之后,系统会检验所选日期范围内的房间是否可以预定。校验通过之后系统创建客房预订订单,状态设置为待支付。用户可以进入订单页面查看自身的订单情况并完成支付。客房预订流程如图4-5所示。

图4-5客房预订流程图
4.3.4 团体订单管理流程设计
旅行社工作人员登录之后进入团体订单列表。系统可以显示所有的未处理团体订单。工作人员选择目标订单查看详情,订单价格和具体需求都会被展示出来。工作人员修改订单接收状态,决定承接这个团体的业务。订单接收之后,系统就会把状态转到行程安排阶段。工作人员可以在客户行程模块中对这个订单的行程进行修改。团体订单管理流程如图4-6所示。

图4-6团体订单管理流程图
4.3.5 订单售后管理流程设计
旅行社工作人员进入到售后管理模块之后查看售后申请列表。按照提交时间倒序对售后记录进行排序。工作人员选择售后申请查看详情,即查看订单编号和售后原因。工作人员填写旅行社回复的内容,说明处理方案。系统将回复的状态改为已处理。用户端可以查看旅行社的回复,并继续进行沟通。订单售后管理流程如图4-7所示。

图4-7订单售后管理流程图
4.4 数据库设计
数据库设计使用关系型数据模型组织业务数据,用表间的关联关系来反映现实世界中业务之间的联系。规范化理论来制定表结构的设计准则,从而降低数据的重复以及更新出现的失误。用户信息、订单记录等使用外键约束建立联系,保证数据一致。事务机制保证门票预订、客房预订等操作是原子性的,即任何部分的操作都必须完成或者都不予完成,不能出现部分成功的数据不一致的情况。索引优化主要是为了提高订单号、景点名称等经常被查询的字段检索的响应速度而采取的一些措施。柯妍等[18]认为MySQL数据库设计要考虑到字段类型的选择以及索引策略对于查询效率的影响。系统的核心实体有普通用户、旅行社、旅游景点、门票预定、酒店信息、酒店客房、客房预订、旅游路线、路线预订、团体订单、客户行程、订单售后等十二个业务实体。
普通用户实体主要包括普通用户id、用户姓名、用户电话、审核状态、用户id、创建时间等属性。实体属性图如图4-8所示。
图4-8普通用户实体属性图
旅行社实体主要包括旅行社id、机构名称、机构电话、审核状态、用户id、创建时间等属性。实体属性图如图4-9所示。
图4-9旅行社实体属性图
旅游景点实体主要包括旅游景点id、景点名称、景点类型、景点位置、门票价格、开放时间、封面图片、景点介绍、点赞数、收藏数、评论数等属性。实体属性图如图4-10所示。
图4-10旅游景点实体属性图
门票预定实体主要包括门票预定id、订单编号、景点名称、景点位置、门票价格、普通用户、用户姓名、用户电话、预定数量、预定总价、预订备注、订单状态等属性。实体属性图如图4-11所示。
图4-11门票预定实体属性图
酒店信息实体主要包括酒店信息id、酒店名称、酒店星级、酒店地址、酒店封面、酒店介绍、点赞数、收藏数、评论数等属性。实体属性图如图4-12所示。
图4-12酒店信息实体属性图
酒店客房实体主要包括酒店客房id、酒店名称、客房编号、客房类型、客房价格、封面图片、详情介绍、点赞数、收藏数、评论数等属性。实体属性图如图4-13所示。
图4-13酒店客房实体属性图
客房预订实体主要包括客房预订id、订单编号、酒店名称、客房编号、客房价格、普通用户、用户姓名、用户电话、预订日期、预订天数、预订总价、预订备注、订单状态等属性。实体属性图如图4-14所示。
图4-14客房预订实体属性图
旅游路线实体主要包括旅游路线id、路线名称、路线价格、起始地点、目的地点、路线封面、路线详情、点赞数、收藏数、评论数等属性。实体属性图如图4-15所示。
图4-15旅游路线实体属性图
路线预订实体主要包括路线预订id、订单编号、路线名称、路线价格、起始地点、目的地点、普通用户、用户姓名、用户电话、预订备注、订单状态等属性。实体属性图如图4-16所示。
图4-16路线预订实体属性图
团体订单实体主要包括团体订单id、订单编号、旅行社、机构名称、机构电话、订单价格、订单详情、订单接收等属性。实体属性图如图4-17所示。
图4-17团体订单实体属性图
客户行程实体主要包括客户行程id、订单编号、旅行社、机构名称、机构电话、订单价格、行程状态、行程详情等属性。实体属性图如图4-18所示。
图4-18客户行程实体属性图
订单售后实体主要包括订单售后id、订单编号、旅行社、机构名称、机构电话、订单价格、售后详情、旅行社回复等属性。实体属性图如图4-19所示。
图4-19订单售后实体属性图
系统同E-R图如图4-20所示。
图4-20系统E-R图
旅游景点表主要是用来存储景区的基本属性与售卖信息。主要包括旅游景点id、景点名称、景点类型、景点位置、门票价格、开放时间、封面图片、景点介绍、点赞数、收藏数、评论数等字段。如表4-1所示。
表4-1旅游景点表
| 1 | 旅游景点id | int 11 | 是 | 旅游景点ID |
| 2 | 景点名称 | varchar 64 | 否 | 景点名称 |
| 3 | 景点类型 | varchar 64 | 否 | 景点类型 |
| 4 | 景点位置 | varchar 64 | 否 | 景点位置 |
| 5 | 门票价格 | double 8,2 | 否 | 门票价格 |
| 6 | 开放时间 | varchar 64 | 否 | 开放时间 |
| 7 | 封面图片 | varchar 255 | 否 | 封面图片 |
| 8 | 景点介绍 | longtext | 否 | 景点介绍 |
| 9 | 点赞数 | int 11 | 是 | 点赞数 |
| 10 | 收藏数 | int 11 | 是 | 收藏数 |
| 11 | 评论数 | int 11 | 是 | 评论数 |
| 12 | 创建时间 | datetime | 是 | 创建时间 |
| 13 | 创建用户id | int 11 | 是 | 创建用户ID |
| 14 | 更新时间 | timestamp | 是 | 更新时间 |
门票预定表主要是用来存储用户提交的门票预订请求记录。主要包括门票预定id、订单编号、景点名称、景点位置、门票价格、普通用户、用户姓名、用户电话、预定数量、预定总价、预订备注、订单状态等字段。如表4-2所示。
表4-2门票预定表
| 1 | 门票预定id | int 11 | 是 | 门票预定ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 景点名称 | varchar 64 | 否 | 景点名称 |
| 4 | 景点位置 | varchar 64 | 否 | 景点位置 |
| 5 | 门票价格 | double 8,2 | 否 | 门票价格 |
| 6 | 普通用户 | int 11 | 否 | 普通用户 |
| 7 | 用户姓名 | varchar 64 | 否 | 用户姓名 |
| 8 | 用户电话 | varchar 64 | 否 | 用户电话 |
| 9 | 预定数量 | double 8,2 | 否 | 预定数量 |
| 10 | 预定总价 | double 8,2 | 否 | 预定总价 |
| 11 | 预订备注 | text | 否 | 预订备注 |
| 12 | 订单状态 | varchar 64 | 否 | 订单状态 |
| 13 | 创建时间 | datetime | 是 | 创建时间 |
| 14 | 创建用户id | int 11 | 是 | 创建用户ID |
| 15 | 更新时间 | timestamp | 是 | 更新时间 |
酒店信息表主要是用来存储合作酒店的概况与评级信息。主要包括酒店信息id、酒店名称、酒店星级、酒店地址、酒店封面、酒店介绍、点赞数、收藏数、评论数等字段。如表4-3所示。
表4-3酒店信息表
| 1 | 酒店信息id | int 11 | 是 | 酒店信息ID |
| 2 | 酒店名称 | varchar 64 | 是 | 酒店名称 |
| 3 | 酒店星级 | varchar 64 | 否 | 酒店星级 |
| 4 | 酒店地址 | varchar 64 | 否 | 酒店地址 |
| 5 | 酒店封面 | varchar 255 | 否 | 酒店封面 |
| 6 | 酒店介绍 | longtext | 否 | 酒店介绍 |
| 7 | 点赞数 | int 11 | 是 | 点赞数 |
| 8 | 收藏数 | int 11 | 是 | 收藏数 |
| 9 | 评论数 | int 11 | 是 | 评论数 |
| 10 | 创建时间 | datetime | 是 | 创建时间 |
| 11 | 创建用户id | int 11 | 是 | 创建用户ID |
| 12 | 更新时间 | timestamp | 是 | 更新时间 |
酒店客房表主要是用来存储每家酒店的具体房型与定价信息。主要包括酒店客房id、酒店名称、客房编号、客房类型、客房价格、封面图片、详情介绍、点赞数、收藏数、评论数等字段。如表4-4所示。
表4-4酒店客房表
| 1 | 酒店客房id | int 11 | 是 | 酒店客房ID |
| 2 | 酒店名称 | varchar 64 | 否 | 酒店名称 |
| 3 | 客房编号 | varchar 64 | 是 | 客房编号 |
| 4 | 客房类型 | varchar 64 | 否 | 客房类型 |
| 5 | 客房价格 | double 8,2 | 否 | 客房价格 |
| 6 | 封面图片 | varchar 255 | 否 | 封面图片 |
| 7 | 详情介绍 | longtext | 否 | 详情介绍 |
| 8 | 点赞数 | int 11 | 是 | 点赞数 |
| 9 | 收藏数 | int 11 | 是 | 收藏数 |
| 10 | 评论数 | int 11 | 是 | 评论数 |
| 11 | 创建时间 | datetime | 是 | 创建时间 |
| 12 | 创建用户id | int 11 | 是 | 创建用户ID |
| 13 | 更新时间 | timestamp | 是 | 更新时间 |
客房预订表主要是用来存储用户提交的酒店客房预订请求。主要包括客房预订id、订单编号、酒店名称、客房编号、客房价格、普通用户、用户姓名、用户电话、预订日期、预订天数、预订总价、预订备注、订单状态等字段。如表4-5所示。
表4-5客房预订表
| 1 | 客房预订id | int 11 | 是 | 客房预订ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 酒店名称 | varchar 64 | 否 | 酒店名称 |
| 4 | 客房编号 | varchar 64 | 否 | 客房编号 |
| 5 | 客房价格 | double 8,2 | 否 | 客房价格 |
| 6 | 普通用户 | int 11 | 否 | 普通用户 |
| 7 | 用户姓名 | varchar 64 | 否 | 用户姓名 |
| 8 | 用户电话 | varchar 64 | 否 | 用户电话 |
| 9 | 预订日期 | date | 否 | 预订日期 |
| 10 | 预订天数 | double 8,2 | 否 | 预订天数 |
| 11 | 预订总价 | double 8,2 | 否 | 预订总价 |
| 12 | 预订备注 | text | 否 | 预订备注 |
| 13 | 订单状态 | varchar 64 | 否 | 订单状态 |
| 14 | 创建时间 | datetime | 是 | 创建时间 |
| 15 | 创建用户id | int 11 | 是 | 创建用户ID |
| 16 | 更新时间 | timestamp | 是 | 更新时间 |
旅游路线表主要是用来存储推荐的旅行线路产品信息。主要包括旅游路线id、路线名称、路线价格、起始地点、目的地点、路线封面、路线详情、点赞数、收藏数、评论数等字段。如表4-6所示。
表4-6旅游路线表
| 1 | 旅游路线id | int 11 | 是 | 旅游路线ID |
| 2 | 路线名称 | varchar 64 | 否 | 路线名称 |
| 3 | 路线价格 | double 8,2 | 否 | 路线价格 |
| 4 | 起始地点 | varchar 64 | 否 | 起始地点 |
| 5 | 目的地点 | varchar 64 | 否 | 目的地点 |
| 6 | 路线封面 | varchar 255 | 否 | 路线封面 |
| 7 | 路线详情 | longtext | 否 | 路线详情 |
| 8 | 点赞数 | int 11 | 是 | 点赞数 |
| 9 | 收藏数 | int 11 | 是 | 收藏数 |
| 10 | 评论数 | int 11 | 是 | 评论数 |
| 11 | 创建时间 | datetime | 是 | 创建时间 |
| 12 | 创建用户id | int 11 | 是 | 创建用户ID |
| 13 | 更新时间 | timestamp | 是 | 更新时间 |
路线预订表主要是用来存储用户提交的旅游路线预订请求。主要包括路线预订id、订单编号、路线名称、路线价格、起始地点、目的地点、普通用户、用户姓名、用户电话、预订备注、订单状态等字段。如表4-7所示。
表4-7路线预订表
| 1 | 路线预订id | int 11 | 是 | 路线预订ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 路线名称 | varchar 64 | 否 | 路线名称 |
| 4 | 路线价格 | double 8,2 | 否 | 路线价格 |
| 5 | 起始地点 | varchar 64 | 否 | 起始地点 |
| 6 | 目的地点 | varchar 64 | 否 | 目的地点 |
| 7 | 普通用户 | int 11 | 否 | 普通用户 |
| 8 | 用户姓名 | varchar 64 | 否 | 用户姓名 |
| 9 | 用户电话 | varchar 64 | 否 | 用户电话 |
| 10 | 预订备注 | text | 否 | 预订备注 |
| 11 | 订单状态 | varchar 64 | 否 | 订单状态 |
| 12 | 创建时间 | datetime | 是 | 创建时间 |
| 13 | 创建用户id | int 11 | 是 | 创建用户ID |
| 14 | 更新时间 | timestamp | 是 | 更新时间 |
团体订单表主要是用来存储旅行社承接的团体客户订单信息。主要包括团体订单id、订单编号、旅行社、机构名称、机构电话、订单价格、订单详情、订单接收等字段。如表4-8所示。
表4-8团体订单表
| 1 | 团体订单id | int 11 | 是 | 团体订单ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 旅行社 | int 11 | 否 | 旅行社 |
| 4 | 机构名称 | varchar 64 | 否 | 机构名称 |
| 5 | 机构电话 | varchar 64 | 否 | 机构电话 |
| 6 | 订单价格 | double 8,2 | 否 | 订单价格 |
| 7 | 订单详情 | text | 否 | 订单详情 |
| 8 | 订单接收 | varchar 64 | 否 | 订单接收 |
| 9 | 创建时间 | datetime | 是 | 创建时间 |
| 10 | 创建用户id | int 11 | 是 | 创建用户ID |
| 11 | 更新时间 | timestamp | 是 | 更新时间 |
客户行程表主要是用来存储团体客户的行程安排与状态记录。主要包括客户行程id、订单编号、旅行社、机构名称、机构电话、订单价格、行程状态、行程详情等字段。如表4-9所示。
表4-9客户行程表
| 1 | 客户行程id | int 11 | 是 | 客户行程ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 旅行社 | int 11 | 否 | 旅行社 |
| 4 | 机构名称 | varchar 64 | 否 | 机构名称 |
| 5 | 机构电话 | varchar 64 | 否 | 机构电话 |
| 6 | 订单价格 | double 8,2 | 否 | 订单价格 |
| 7 | 行程状态 | varchar 64 | 否 | 行程状态 |
| 8 | 行程详情 | text | 否 | 行程详情 |
| 9 | 创建时间 | datetime | 是 | 创建时间 |
| 10 | 创建用户id | int 11 | 是 | 创建用户ID |
| 11 | 更新时间 | timestamp | 是 | 更新时间 |
订单售后表主要是用来存储客户发起的售后申请与旅行社回复内容。主要包括订单售后id、订单编号、旅行社、机构名称、机构电话、订单价格、售后详情、旅行社回复等字段。如表4-10所示。
表4-10订单售后表
| 1 | 订单售后id | int 11 | 是 | 订单售后ID |
| 2 | 订单编号 | varchar 64 | 否 | 订单编号 |
| 3 | 旅行社 | int 11 | 否 | 旅行社 |
| 4 | 机构名称 | varchar 64 | 否 | 机构名称 |
| 5 | 机构电话 | varchar 64 | 否 | 机构电话 |
| 6 | 订单价格 | double 8,2 | 否 | 订单价格 |
| 7 | 售后详情 | text | 否 | 售后详情 |
| 8 | 旅行社回复 | text | 否 | 旅行社回复 |
| 9 | 创建时间 | datetime | 是 | 创建时间 |
| 10 | 创建用户id | int 11 | 是 | 创建用户ID |
| 11 | 更新时间 | timestamp | 是 | 更新时间 |
普通用户表主要是用来存储注册用户的身份信息与联系方式。主要包括普通用户id、用户姓名、用户电话、审核状态、用户id、创建时间等字段。如表4-11所示。
表4-11普通用户表
| 1 | 普通用户id | int 11 | 是 | 普通用户ID |
| 2 | 用户姓名 | varchar 64 | 否 | 用户姓名 |
| 3 | 用户电话 | varchar 64 | 否 | 用户电话 |
| 4 | 审核状态 | varchar 16 | 是 | 审核状态 |
| 5 | 用户id | int 11 | 是 | 用户ID |
| 6 | 创建时间 | datetime | 是 | 创建时间 |
| 7 | 创建用户id | int 11 | 是 | 创建用户ID |
| 8 | 更新时间 | timestamp | 是 | 更新时间 |
旅行社表主要是用来存储合作旅行社的基本资料与联系渠道。主要包括旅行社id、机构名称、机构电话、审核状态、用户id、创建时间等字段。如表4-12所示。
表4-12旅行社表
| 1 | 旅行社id | int 11 | 是 | 旅行社ID |
| 2 | 机构名称 | varchar 64 | 否 | 机构名称 |
| 3 | 机构电话 | varchar 64 | 否 | 机构电话 |
| 4 | 审核状态 | varchar 16 | 是 | 审核状态 |
| 5 | 用户id | int 11 | 是 | 用户ID |
| 6 | 创建时间 | datetime | 是 | 创建时间 |
| 7 | 创建用户id | int 11 | 是 | 创建用户ID |
| 8 | 更新时间 | timestamp | 是 | 更新时间 |
第五章 系统实现
5.1 普通用户功能实现
5.1.1 注册登录功能实现
普通用户通过登录接口提交用户名与密码,后端UserController的login方法接收请求。该方法对密码进行解密后,根据用户名查询用户信息,验证用户状态并生成Token存储于Redis中,最后返回用户信息与Token。注册功能通过signUp方法接收用户数据并存入数据库。注册登录界面如图5-1所示。
图5-1注册登录界面
核心代码实现如下:
@PostMapping("login")
public Map<String, Object> login(@RequestBody Map<String, String> data, HttpServletRequest httpServletRequest) {
String username = data.get("username");
String password = data.get("password");
password = RsaUtils.decryptByPrivateKey(password);
List resultList = service.selectBaseList(service.select(map, new HashMap<>()));
AccessToken accessToken = new AccessToken();
accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
redisTemplate.opsForValue().set(accessToken.getToken(), accessToken, duration);
}
5.1.2 旅游景点查看功能实现
旅游景点查看通过TouristAttractionController的get_list方法实现。该方法接收前端查询条件,调用服务层select方法根据参数检索景点数据,并返回包含景点列表与总数量的结果集。普通用户无需特殊权限即可浏览所有景点信息。旅游景点查看界面如图5-2所示。
图5-2旅游景点查看界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.1.3 酒店信息查看功能实现
酒店信息查看功能由HotelInformationController的get_list方法提供。系统从请求中读取查询条件与配置参数,服务层根据条件检索酒店信息数据,控制器将查询结果列表与总记录数封装后返回前端展示。酒店信息查看界面如图5-3所示。
图5-3酒店信息查看界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.1.4 酒店客房查看功能实现
酒店客房查看功能通过HotelRoomController的get_list方法实现。系统解析请求中的查询参数,调用服务层select方法从数据库获取客房信息,控制器将结果列表与符合条件的总记录数封装为Map对象返回给前端。酒店客房查看界面如图5-4所示。
图5-4酒店客房查看界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.1.5 旅游路线查看功能实现
旅游路线查看功能由TouristRouteController的get_list方法实现。前端提交查询参数后,控制器读取条件并调用服务层进行数据检索,返回路线列表与总数。用户可查看路线名称、价格、起止点等详细信息。旅游路线查看界面如图5-5所示。
图5-5旅游路线查看界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.1.6 门票预订功能实现
门票预订功能通过TicketReservationController的add方法实现。系统接收预订信息后,先过滤空值字段,创建TicketReservation实体对象并设置订单编号、景点名称、价格、数量等属性,最终调用addEntity方法将预订记录插入数据库。门票预订界面如图5-6所示。
图5-6门票预订界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
paramMap.entrySet().removeIf(entry -> {
Object value = entry.getValue();
return value instanceof String && ((String) value).isEmpty();
});
TicketReservation ticket_reservation = new TicketReservation();
ticket_reservation.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
this.addEntity(ticket_reservation);
}
5.1.7 客房预订功能实现
客房预订功能由RoomReservationController的add方法实现。控制器读取请求体参数,过滤空白字符串后构建RoomReservation对象,设置订单号、酒店名称、客房编号、入住日期等字段,通过addEntity方法完成数据持久化操作。客房预订界面如图5-7所示。
图5-7客房预订界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
paramMap.entrySet().removeIf(entry -> {
Object value = entry.getValue();
return value instanceof String && ((String) value).isEmpty();
});
RoomReservation room_reservation = new RoomReservation();
room_reservation.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
this.addEntity(room_reservation);
}
5.1.8 路线预订功能实现
路线预订功能通过RouteBookingController的add方法实现。系统接收预订请求后,将参数封装为RouteBooking实体,包含路线名称、价格、起止点、用户信息等字段,调用addEntity方法插入预订记录,并返回操作成功状态。路线预订界面如图5-8所示。
图5-8路线预订界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
paramMap.entrySet().removeIf(entry -> {
Object value = entry.getValue();
return value instanceof String && ((String) value).isEmpty();
});
RouteBooking route_booking = new RouteBooking();
route_booking.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
this.addEntity(route_booking);
}
5.1.9 门票订单管理功能实现
门票订单管理功能由TicketOrderController的get_list与update_pay_state方法实现。get_list方法分页查询用户订单,update_pay_state方法接收订单ID与新状态,根据ID查找记录后更新支付状态字段,实现订单状态变更。门票订单管理界面如图5-9所示。
图5-9门票订单管理界面
核心代码实现如下:
@GetMapping("/update_pay_state")
@Transactional
public String updatePayState(Long id, String newState) throws IOException {
Map<String,String> queryMap = new HashMap<>();
queryMap.put("id",String.valueOf(id));
TicketOrder ticket_order = service.findOne(queryMap);
ticket_order.setPay_state(newState);
this.setEntity(queryMap,new HashMap<>(),ticket_order);
return "支付成功";
}
5.1.10 客房订单管理功能实现
客房订单管理功能通过RoomOrderController的get_list与update_pay_state方法实现。get_list方法根据用户ID查询订单列表,update_pay_state方法根据订单ID修改支付状态,支持从“未支付”变更为“已支付”,操作完成后返回提示信息。客房订单管理界面如图5-10所示。
图5-10客房订单管理界面
核心代码实现如下:
@GetMapping("/update_pay_state")
@Transactional
public String updatePayState(Long id, String newState) throws IOException {
Map<String,String> queryMap = new HashMap<>();
queryMap.put("id",String.valueOf(id));
RoomOrder room_order = service.findOne(queryMap);
room_order.setPay_state(newState);
this.setEntity(queryMap,new HashMap<>(),room_order);
return "支付成功";
}
5.1.11 路线订单管理功能实现
路线订单管理功能由RouteOrderController的get_list与update_pay_state方法实现。get_list方法支持条件查询用户路线订单,update_pay_state方法接收订单ID与新状态,通过setEntity更新支付状态字段,确保订单状态同步。路线订单管理界面如图5-11所示。
图5-11路线订单管理界面
核心代码实现如下:
@GetMapping("/update_pay_state")
@Transactional
public String updatePayState(Long id, String newState) throws IOException {
Map<String,String> queryMap = new HashMap<>();
queryMap.put("id",String.valueOf(id));
RouteOrder route_order = service.findOne(queryMap);
route_order.setPay_state(newState);
this.setEntity(queryMap,new HashMap<>(),route_order);
return "支付成功";
}
5.2 旅行社功能实现
5.2.1 团体订单管理功能实现
团体订单管理功能通过GroupOrderController的add与set方法实现。add方法接收前端参数构建GroupOrder实体并插入数据库,set方法根据查询条件更新订单信息,支持订单编号、机构名称、订单价格等字段的修改操作。团体订单管理界面如图5-12所示。
图5-12团体订单管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
GroupOrder group_order = new GroupOrder();
group_order.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
group_order.setTravel_agency(paramMap.get("travel_agency")==null?null:Integer.valueOf(String.valueOf(paramMap.get("travel_agency"))));
this.addEntity(group_order);
return success(1);
}
5.2.2 客户行程管理功能实现
客户行程管理功能由CustomerItineraryController的add与set方法实现。add方法创建客户行程记录,包含订单号、旅行社、行程详情等字段,set方法支持根据查询条件修改行程状态与具体内容,方便旅行社调整客户安排。客户行程管理界面如图5-13所示。
图5-13客户行程管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
CustomerItinerary customer_itinerary = new CustomerItinerary();
customer_itinerary.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
customer_itinerary.setTravel_agency(paramMap.get("travel_agency")==null?null:Integer.valueOf(String.valueOf(paramMap.get("travel_agency"))));
this.addEntity(customer_itinerary);
}
5.2.3 订单售后管理功能实现
订单售后管理功能通过AfterSalesServiceForOrdersController的add与set方法实现。add方法接收售后申请参数,记录订单编号、售后具体内容等,set方法允许旅行社回复售后请求,更新travel_agency_reply字段,实现售后流程处理。订单售后管理界面如图5-14所示。
图5-14订单售后管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
AfterSalesServiceForOrders after_sales_service_for_orders = new AfterSalesServiceForOrders();
after_sales_service_for_orders.setOrder_number(paramMap.get("order_number")==null?null:String.valueOf(paramMap.get("order_number")));
after_sales_service_for_orders.setTravel_agency_reply(paramMap.get("travel_agency_reply")==null?null:String.valueOf(paramMap.get("travel_agency_reply")));
this.addEntity(after_sales_service_for_orders);
}
5.2.4 留言反馈管理功能实现
留言反馈管理功能由MessageFeedbackController的add与set方法实现。add方法接收用户提交的反馈类型与内容,set方法支持旅行社回复用户留言,更新manageristrator_reply字段,实现双向沟通与管理。留言反馈管理界面如图5-15所示。
图5-15留言反馈管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
MessageFeedback message_feedback = new MessageFeedback();
message_feedback.setFeedback_type(paramMap.get("feedback_type")==null?null:String.valueOf(paramMap.get("feedback_type")));
message_feedback.setFeedback_content(paramMap.get("feedback_content")==null?null:String.valueOf(paramMap.get("feedback_content")));
this.addEntity(message_feedback);
}
5.2.5 合作数据管理功能实现
合作数据管理功能通过CollaborationDataController的add与set方法实现。add方法新增合作记录,包含合作类型、收益金额、收益日期等字段,set方法支持修改合作描述或收益数据,便于旅行社维护合作伙伴信息。合作数据管理界面如图5-16所示。
图5-16合作数据管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
CollaborationData collaboration_data = new CollaborationData();
collaboration_data.setType_of_cooperation(paramMap.get("type_of_cooperation")==null?null:String.valueOf(paramMap.get("type_of_cooperation")));
collaboration_data.setBenefits_of_cooperation(paramMap.get("benefits_of_cooperation")==null?null:Double.valueOf(String.valueOf(paramMap.get("benefits_of_cooperation"))));
this.addEntity(collaboration_data);
}
5.3 管理员功能实现
团体订单管理功能实现
管理员团体订单管理通过GroupOrderController的get_list、add与set方法实现。get_list支持全量查询所有团体订单,add方法新增订单,set方法修改订单状态与详情,管理员拥有比旅行社更全面的订单操作权限。团体订单管理界面如图5-17所示。
图5-17团体订单管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.1 客户行程管理功能实现
客户行程管理功能由CustomerItineraryController的get_list与set方法实现。管理员可查询所有客户的行程安排,通过set方法修改行程状态与具体内容,确保行程信息准确,并在必要时进行干预调整。客户行程管理界面如图5-18所示。
图5-18客户行程管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.2 订单售后管理功能实现
订单售后管理功能通过AfterSalesServiceForOrdersController的get_list与set方法实现。管理员可查看所有售后申请,通过set方法更新旅行社回复内容或直接处理售后请求,具备最终审核与裁决权限。订单售后管理界面如图5-19所示。
图5-19订单售后管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.3 合作数据管理功能实现
合作数据管理功能由CollaborationDataController的get_list与set方法实现。管理员维护所有合作方数据,支持按合作类型、收益日期等条件检索,并通过set方法修改合作收益与描述,保障数据准确性。合作数据管理界面如图5-20所示。
图5-20合作数据管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.4 景点类型管理功能实现
景点类型管理功能通过TypeOfAttractionController的add与set方法实现。add方法接收景点类型名称并插入数据库,set方法根据查询条件修改类型名称,管理员可对景点分类进行增删改查操作。景点类型管理界面如图5-21所示。
图5-21景点类型管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
TypeOfAttraction type_of_attraction = new TypeOfAttraction();
type_of_attraction.setAttraction_type(paramMap.get("attraction_type")==null?null:String.valueOf(paramMap.get("attraction_type")));
this.addEntity(type_of_attraction);
return success(1);
}
5.3.5 旅游景点管理功能实现
旅游景点管理功能由TouristAttractionController的add与set方法实现。add方法新增景点信息,包含名称、类型、位置、门票价格等字段,set方法支持修改景点介绍与封面图,管理员可完整管理景点资源。旅游景点管理界面如图5-22所示。
图5-22旅游景点管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
TouristAttraction tourist_attraction = new TouristAttraction();
tourist_attraction.setAttraction_name(paramMap.get("attraction_name")==null?null:String.valueOf(paramMap.get("attraction_name")));
tourist_attraction.setTicket_prices(paramMap.get("ticket_prices")==null?null:Double.valueOf(String.valueOf(paramMap.get("ticket_prices"))));
this.addEntity(tourist_attraction);
}
5.3.6 门票预订管理功能实现
门票预订管理功能通过TicketReservationController的get_list与set方法实现。管理员可查询所有用户的门票预订记录,通过set方法修改订单状态与备注,实现对预订流程的监督与管理。门票预订管理界面如图5-23所示。
图5-23门票预订管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.7 门票订单管理功能实现
门票订单管理功能由TicketOrderController的get_list与update_pay_state方法实现。管理员可查看所有门票订单,通过update_pay_state方法修改任意订单的支付状态,具备比普通用户更完整的管理权限。门票订单管理界面如图5-24所示。
图5-24门票订单管理界面
核心代码实现如下:
@GetMapping("/update_pay_state")
@Transactional
public String updatePayState(Long id, String newState) throws IOException {
Map<String,String> queryMap = new HashMap<>();
queryMap.put("id",String.valueOf(id));
TicketOrder ticket_order = service.findOne(queryMap);
ticket_order.setPay_state(newState);
this.setEntity(queryMap,new HashMap<>(),ticket_order);
return "支付成功";
}
5.3.8 酒店信息管理功能实现
酒店信息管理功能通过HotelInformationController的add与set方法实现。add方法新增酒店记录,包含酒店名称、星级、地址、介绍等,set方法支持修改酒店信息,管理员可维护完整的酒店资源库。酒店信息管理界面如图5-25所示。
图5-25酒店信息管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
HotelInformation hotel_information = new HotelInformation();
hotel_information.setHotel_name(paramMap.get("hotel_name")==null?null:String.valueOf(paramMap.get("hotel_name")));
hotel_information.setHotel_introduction(paramMap.get("hotel_introduction")==null?null:String.valueOf(paramMap.get("hotel_introduction")));
this.addEntity(hotel_information);
}
5.3.9 客房订单管理功能实现
客房订单管理功能由RoomOrderController的get_list与update_pay_state方法实现。管理员可检索所有客房订单,并通过update_pay_state方法批量或单独修改订单支付状态,确保订单数据一致性。客房订单管理界面如图5-26所示。
图5-26客房订单管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
5.3.10 旅游路线管理功能实现
旅游路线管理功能通过TouristRouteController的add与set方法实现。add方法新增路线,包含名称、价格、起止点、路线详情等,set方法支持修改路线信息,管理员可对旅游路线进行全面的维护管理。旅游路线管理界面如图5-27所示。
图5-27旅游路线管理界面
核心代码实现如下:
@PostMapping("/add")
@Transactional
public Map<String, Object> add(HttpServletRequest request) throws IOException {
Map<String,Object> paramMap = service.readBody(request.getReader());
TouristRoute tourist_route = new TouristRoute();
tourist_route.setRoute_name(paramMap.get("route_name")==null?null:String.valueOf(paramMap.get("route_name")));
tourist_route.setRoute_price(paramMap.get("route_price")==null?null:Double.valueOf(String.valueOf(paramMap.get("route_price"))));
this.addEntity(tourist_route);
}
5.3.11 路线订单管理功能实现
路线订单管理功能由RouteOrderController的get_list与update_pay_state方法实现。管理员可查询所有用户的路线订单,通过update_pay_state方法直接修改订单支付状态,实现订单的全流程监管。路线订单管理界面如图5-28所示。
图5-28路线订单管理界面
核心代码实现如下:
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, String> query = service.readQuery(request);
Map<String, String> config = service.readConfig(request);
List list = this.service.selectBaseList(this.service.select(query, config));
map.put("list",list);
map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
return success(map);
}
第六章 系统测试
6.1 测试目的
系统测试主要目的是检验旅行社网站各个功能模块是否达到设计出的要求。测试过程包含用户登录、产品预订、订单管理、后台维护这些主要的业务环节,测试的时候检查数据流转的准确性以及一致性。用边界值测试检验系统对于异常输入的处理情况,比如预订数量超过库存上限的情况。测试还要验证各个角色之间权限隔离,保证旅行社不能操作管理员权限的功能。周喜平[19]认为微服务架构下的系统测试主要是对接口契约和数据一致性进行的测试。测试结果可以给系统上线前缺陷的修改提供依据,减小运行阶段所造成的风险。
6.2 测试方法
使用黑盒测试的方法来对系统进行测试,主要是关注功能实现和需求规格是否一致。根据各个角色功能模块设计出测试用例,包含正常业务流程和异常分支的测试用例。功能测试就是对景点查看、预定提交、订单查询等操作是否正确进行检验。集成测试是对前后端接口的数据交互进行测试的过程,主要是检查请求参数、响应格式等各方面的内容,以保证符合约定。回归测试是在缺陷修复之后再进行的,用来检验修改没有引入新的问题。测试环境使用独立的数据库,测试数据和生产数据相互独立。
6.3 测试用例
(1)普通用户登录功能测试如表6-1所示。
表6-1普通用户登录功能测试
| 正确凭证登录 | 输入正确用户名密码后提交 | 成功登录跳转首页 | 符合预期 |
| 错误密码登录 | 输入正确用户名错误密码 | 提示密码错误 | 符合预期 |
| 空字段提交 | 用户名或密码为空时提交 | 提示填写完整信息 | 符合预期 |
(2)门票预订功能测试如表6-2所示。
表6-2门票预订功能测试
| 正常预订提交 | 选择景点填写数量后提交 | 生成待支付订单 | 符合预期 |
| 库存不足预订 | 预订数量超过剩余库存 | 提示库存不足 | 符合预期 |
| 未登录预订 | 未登录状态下点击预订 | 跳转登录页面 | 符合预期 |
(3)客房预订功能测试如表6-3所示。
表6-3客房预订功能测试
| 日期选择预订 | 选择入住离店日期后提交 | 正确计算天数总价 | 符合预期 |
| 重复预订检测 | 对已订日期再次预订 | 提示日期不可用 | 符合预期 |
| 入住日期校验 | 选择过去日期提交 | 提示日期无效 | 符合预期 |
(4)旅行社团体订单管理测试如表6-4所示。
表6-4旅行社团体订单管理测试
| 订单接收操作 | 选中订单点击接收 | 状态变为已接收 | 符合预期 |
| 订单列表筛选 | 按状态筛选订单 | 显示对应状态订单 | 符合预期 |
| 详情查看 | 点击订单查看详情 | 显示完整订单信息 | 符合预期 |
(5)管理员景点管理测试如表6-5所示。
表6-5管理员景点管理测试
| 新增景点 | 填写景点信息后保存 | 景点出现在列表 | 符合预期 |
| 编辑景点 | 修改景点价格后保存 | 价格更新生效 | 符合预期 |
| 下架景点 | 执行下架操作 | 前台不再显示 | 符合预期 |
测试结论
测试用例执行之后所有功能模块都被测试过了。普通用户的注册登录成功、购买商品和管理订单的响应也都正确。旅行社团体订单的接收以及客户的行程状态的更新是正常的。管理员对于景点、酒店、路线的增加、删除、修改和查看都符合预期。边界条件测试的时候系统可以识别出库存不足,日期冲突这些异常情况并且给出相应的提示。权限控制测试结果表明各个角色不能越权访问未授权的功能。从测试结果可以得出该系统满足了设计的要求,具备上线条件。
项目分享:大家可自取用于参考学习,获取方式可私信哦!
网硕互联帮助中心
![可白嫖源码---课程设计--课程设计--毕业设计-- springboot停车场车位停车管理系统[编号:project62330] (案件分析)-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/09/20260922063407-6ab2215f182f3-220x150.png)



评论前必须登录!
注册