项目编号:BS-PT-087
一,环境介绍
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
二,项目简介
2.1 项目背景
市场上现有的一些旅游信息平台如携程旅游、途牛、马蜂窝等旅游信息平台只能满足用户的部分需求,无法给广大用户带来最好的体验。并且平台与当地景点推送和政策等信息更新不及时,用户与旅游之间信息不互通的矛盾未得到解决,当旅游目的地的政策发生了改变时,用户不能够及时的了解到,可能需要通过其他的平台来获取当地最新的旅游资讯,如果一些用户没有通过其他平台去了解当地信息时,可能会发生“白跑一趟”等现象,降低用户的体验感。
本文旅游信息平台系统的设计与实现吸收了市场上其他旅游信息系统的长处,也重视信息互通不及时、用户体验感和交互性等问题。为解决用户与旅游之间的不确定性,不信任性和不简便性等矛盾,实现用户与旅游之间到的信息可视化,信息安全化,服务个性化等特点,给用户带来更友好,舒适的旅游体验。
随着社会时代的发展已经迈入了2022年的阶梯,整个社会的经济发展模式已经和以往产生了非常大的改变。兴起的服务行业对国家的经济发展已然成为了主要推动力之一,而旅游业作为服务行业重要的模块之一也越来越受到人们的重视。旅游得到了飞速的发展。行业规模不断扩大已经成为国家的重点发展项目,旅游市场逐步扩大。随着市场经济的发展和人民收入水平的进一步提高,人们对旅游消费的需求也越来越大,所以旅游业在国民经济中的地位和作用至关重要。发展旅游业具有十分重要的意义。
旅游业的高速发展也带来了管理方面的挑战,多方面的信息汇入,智能信息体系的建设迫在眉睫。兴起的IT行业作为信息技术产业,它是运用信息手段和技术,收集、整理、储存、传递信息情报,提供信息服务,并提供相应的信息手段、信息技术等服务。现如今,IT领域的技术不断地攻克在企业级项目开发、微服务、大数据等方向都取得了重大的数据突破。使用现代技术促进旅游产业的持续稳定发展已然成为了未来发展方向,搭建旅游信息平台实现数据的便捷管理也必然成为趋势。
2.2 功能需求分析
后台管理系统模块:前台展示管理、用户管理、管理员管理、酒店管理、机票管理、火车票管理、攻略景点管理、订单管理、系统统计、管理员管理等功能。它包括对用户前台、用户信息、管理员信息、酒店信息、机票信息、攻略与景点信息、系统数据信息、订单信息的管理。
前台系统模块:包含前台展示、用户模块、酒店模块、机票模块、火车票模块、攻略景点模块、订单模块等,主要有用户与游客可以在前台系统中注册账号、登录系统、浏览所有商品(包括酒店、机票、火车票、景点门票)信息、购买商品,查看订单等操作。会员系统模块:用户可以查询系统中的订单、管理订单、优惠券等信息。
用户系统模块:用户可以注册账号、登录账号、修改个人信息比如密码,头像等,未登录的用户只能享受系统的部分功能,如酒店信息的查询,无法进行酒店房间预定服务。
订单系统模块:系统用户可以在本系统构面或预定酒店、机票、火车票、景区门票等,购买或预定完成会有相应的订单信息,用户可以通过订单或者根据账号信息查看或者修改订单信息。
单点登录系统模块:在本多个应用系统中,用户只需要登录一次就可以访问本平台所有的系统。
酒店系统模块:用户可以查看酒店信息,包括按城市、名称、评分、位置等搜索自己想要的酒店信息,同时还提供酒店信息排行榜,帮助用户快速的找到自己想要的酒店信息。酒店系统先通过查找酒店,再通过酒店查找所属的房间信息,完成房间的预定。
机票系统模块:用户可以按日期、出发城市以及目的地城市作为查询条件查询机票信息。
火车票系统模块:用户可以按日期、出发城市以及目的地城市作为查询条件查询火车票信息。
攻略与景点模块:该模块包括景点门票的购买以及攻略的分享。景点门票可通过城市、景点名称进行模糊查询。同时设置了一个景点热度榜,显示最近比较热度的景点,吸引用户打卡。
其主要功能模块图如图1所示
图1功能模块图
2.3 系统设计
本旅游信息平台基于spring cloud微服务技术部署的Web项目,根据预计的需求,开发难度和性能需求等采用的架构形式是分层架构。系统的具体分层架构部署如图2所示。
图2系统部署图
系统分为前后台用户,前台用户主要是普通用户,普通用户包括登录用户和未登录用户。根据是否登录状态,用户访问的范围以及能够使用的功能都是不同的。后台用户主要是后台维护人员和后台管理员用户。前后台的用户访问范围资源如图3、图4所示。
图3旅游信息平台前台用例图
图4旅游信息平台后台
三,系统展示
3.1 前台登录注册的实现
用户进入系统可以在界面点击登录跳转到登录界面,如果用户点击查询订单和创建订单等功能,在未登录的状态下也会直接跳转到登录界面,登录界面有跳转注册界面的路径。账号注册的实现,用户通过输入手机号、账号密码、邮箱账号等信息,用户需要二次确认密码,两次密码相同才能注册。每个手机号只能创建一个账号,注册时会进行手机号验证。登录的实现,用户输入手机号、密码,也可以选择通过手机号验证进行登录。实现的UI界面如图3-1、图3-2所示。
图3-1用户注册UI图
图3-2用户登录UI图
3.2 酒店模块实现
酒店模块是用户进入系统的首个展示的模块,酒店模块首页设有酒店信息搜索和酒店的推荐以及酒店排行榜信息的宣传。酒店搜索,通过根据酒店名称,所在城市,位置等信息进行模糊查询,搜索会跳转到酒店信息列表页面,展示酒店的信息,同时会在页面展示一个酒店的地图位置信息。用户可以点击推荐的酒店直接进入该酒店详情和通过在酒店列表点击查看详情进入酒店详情,酒店详情展示酒店的详细介绍和该酒店所属的房间信息,用户可以在此界面上进行房间的预定,创建订单完成酒店预定,预定好的房间会被锁定,其他用户无法查看到该房间信息状态。实现的UI界面如图3-3、3-4、3-5所示。
图3-3 酒店首页UI图
图3-4酒店查询UI界面
图3-5酒店详情与房间信息UI图
3.3 机票模块实现
用户通过侧边栏跳转到机票模块,机票实现上方是为机票信息的搜索,通过目的地城市、出发地城市、出发机场、目的地机场,时间作为机票的查询条件。查询结果为空的话,将会弹出提示,查询到的信息可以通过时间和价格进行排序,实现的UI界面如图5-6所示。
图3-6 机票信息UI图
3.4 火车票模块实现
用户通过侧边栏可以进入火车票模块,火车票的搜索提供时间,城市、列车类型(包括高铁、动车、火车)作为查询条件,用户可以直接在火车列表通过购票按钮直接进入火车票创建订单界面。当地点改变时,页面会弹出一个出发地和目的地政策内容用于通知用户。用户可以直接通过机票列表点击购票进入创建订单功能。实现的UI界面如图3-7、图3-8所示。
图3-7 地方政策自动发送UI图
图3-8火车票信息展示UI图
3.5 景点模块功能实现
景点模块主要是方便景区门票的购买,用户通过城市、景点名称(模糊查询)查询景点,通过景点列表点击详情或者通过酒店推荐榜,可以进入查看该景区的详细信息,包括景点介绍、服务措施、公共设施等内容,用户也可以在此界面进行景点门票的购买。实现的UI界面如图5-9所示。
图3-9 景点信息UI图
图3-10酒店详细信息UI图
3.6 攻略模块实现
攻略模块主要是用户发布的景点攻略和景点攻略的查看,攻略可以进行点赞和评论。实现的UI界面如图5-10、图5-11所示。
图3-10攻略信息UI图
图5-11攻略详情UI图
3.7 用户模块实现
用户模块主要是用户信息查看以及用户信息修改,同时用户可以查看本人的各种类型订单。实现的UI界面如图5-12所示。
图3-12 用户中心UI图
5.8 订单模块实现
订单模块主要是用户在购买或预定酒店、火车票、机票、景区门票时创建订单,创建订单时会展示订单的一个基本信息包括订单号,订单金额等信息。用户可以选择支付方式进行支付,支付成功会跳转到一个支付成功提示的界面。实现的UI界面如图5-13、图5-14所示。
图3-13支付界面UI图
图3-14支付成功提示UI图
3.9 后台首页实现
后台首页是管理员进入后台管理界面展示的首张页面,页面主要是图表、统计等一些信息。管理员可以直观的看到订单数量、用户注册人数、全部订单金额等数据内容。实现的UI界面如图3-15所示。
图3-15 后台首页UI界面
四,核心代码展示
package com.lypt.controller.admin; import com.lypt.api.CommonResult; import com.lypt.pojo.vo.*; import com.lypt.service.*; import com.lypt.uitls.ComparatorSort; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @RestController @RequestMapping("/admin/echarts") public class AdminEchartsController { @Autowired TrainOrderService trainOrderService; @Autowired ScenicOrderService scenicOrderService; @Autowired PlaneOrderService planeOrderService; @Autowired BookOrderService bookOrderService; @Autowired UserService userService; @RequestMapping("/topData") public CommonResult topData(){ AdminTopData adminTopData = new AdminTopData(); //用户数量 adminTopData.setUserNumber(userService.AllUserNumber()); //一周销售额 Double totalPrice = 0.00; totalPrice+= trainOrderService.weekData(); totalPrice+= scenicOrderService.weekData(); totalPrice+=planeOrderService.weekData(); totalPrice+= bookOrderService.weekData(); adminTopData.setWeekSalesVolume(totalPrice); AllTypeOrderData allTypeOrderData1 = trainOrderService.allOrderData(); AllTypeOrderData allTypeOrderData2 = scenicOrderService.allOrderData(); AllTypeOrderData allTypeOrderData3 = planeOrderService.allOrderData(); AllTypeOrderData allTypeOrderData4 = bookOrderService.allOrderData(); //所有订单数量 int totalNumber = 0; totalNumber+=allTypeOrderData1.getTotal(); totalNumber+=allTypeOrderData2.getTotal(); totalNumber+=allTypeOrderData3.getTotal(); totalNumber+=allTypeOrderData4.getTotal(); adminTopData.setAllOrderNumber(totalNumber); //总销售额 Double allOrderPrice = 0.00; allOrderPrice+=allTypeOrderData1.getTotalPrice(); allOrderPrice+=allTypeOrderData2.getTotalPrice(); allOrderPrice+=allTypeOrderData3.getTotalPrice(); allOrderPrice+=allTypeOrderData4.getTotalPrice(); adminTopData.setAllSalesVolume(allOrderPrice); return CommonResult.success(adminTopData); } @RequestMapping("/weekBuyRanking") public CommonResult weekBuyRanking(){ WeekSalesVolume weekSalesVolume1 = new WeekSalesVolume(); WeekSalesVolume weekSalesVolume2 = new WeekSalesVolume(); WeekSalesVolume weekSalesVolume3 = new WeekSalesVolume(); WeekSalesVolume weekSalesVolume4 = new WeekSalesVolume(); weekSalesVolume1.setTypeName("酒店"); weekSalesVolume1.setMoney(bookOrderService.weekData()); weekSalesVolume2.setTypeName("机票"); weekSalesVolume2.setMoney(planeOrderService.weekData()); weekSalesVolume3.setTypeName("火车票"); weekSalesVolume3.setMoney(trainOrderService.weekData()); weekSalesVolume4.setTypeName("景点门票"); weekSalesVolume4.setMoney(scenicOrderService.weekData()); ArrayList<Object> list = new ArrayList<>(); list.add(weekSalesVolume1); list.add(weekSalesVolume2); list.add(weekSalesVolume3); list.add(weekSalesVolume4); ComparatorSort comparatorSort = new ComparatorSort(); Collections.sort(list,comparatorSort); return CommonResult.success(list); } @RequestMapping("/allBuyTotal") public CommonResult allBuyTotal(){ ArrayList<Object> list = new ArrayList<>(); AllSalesVolume allSalesVolume1 = new AllSalesVolume(); AllSalesVolume allSalesVolume2 = new AllSalesVolume(); AllSalesVolume allSalesVolume3 = new AllSalesVolume(); AllSalesVolume allSalesVolume4 = new AllSalesVolume(); allSalesVolume1.setName("酒店"); allSalesVolume1.setValue(bookOrderService.allOrderData().getTotalPrice()); allSalesVolume2.setName("机票"); allSalesVolume2.setValue(planeOrderService.allOrderData().getTotalPrice()); allSalesVolume3.setName("火车票"); allSalesVolume3.setValue(trainOrderService.allOrderData().getTotalPrice()); allSalesVolume4.setName("景区门票"); allSalesVolume4.setValue(scenicOrderService.allOrderData().getTotalPrice()); list.add(allSalesVolume1); list.add(allSalesVolume2); list.add(allSalesVolume3); list.add(allSalesVolume4); return CommonResult.success(list); } @RequestMapping("/weekScenicDay") public CommonResult weekScenicDay(){ WeekOnDay weekOnDay = scenicOrderService.weekOrderNumber(); return CommonResult.success(weekOnDay); } }
package com.lypt.controller.admin; import com.github.pagehelper.PageInfo; import com.lypt.api.CommonResult; import com.lypt.pojo.springcloud_graduation.Manage; import com.lypt.pojo.vo.Page; import com.lypt.pojo.vo.Users; import com.lypt.pojo.vo.Users2; import com.lypt.service.ManageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; @PropertySource("classpath:nginxconfig.properties") @RestController @RequestMapping("/admin") public class AdminManageController { @Value("${pichost}") private String pichost; @Autowired ManageService manageService; @RequestMapping("/userInfo") public CommonResult userInfo(){ ArrayList<String> list = new ArrayList<>(); list.add("admin"); Users user = new Users(); user.setUsername("admin"); user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"); user.setPermissions(list); return CommonResult.success(user); } @RequestMapping("/login") public CommonResult login(){ Users2 users2 = new Users2(); users2.setAccessToken("admin"); return CommonResult.success(users2); } @RequestMapping("/manage/getAllList") public CommonResult getAllList(Page page,Manage manage){ List<Manage> allList = manageService.getAllList(page, manage); PageInfo pageInfo = new PageInfo(allList); return CommonResult.success(pageInfo); } /** * 上传图片 * @param tupian * @return */ @RequestMapping("/manage/uploadImg") public CommonResult uploadFile(MultipartFile tupian){ System.out.println("nihao"); String url=null; if(tupian!=null&&!tupian.isEmpty()){ String name= UUID.randomUUID().toString();//生成随机的uuid作为文件名 int pos=tupian.getOriginalFilename().lastIndexOf(".");//后缀的位置 String fileName=name+tupian.getOriginalFilename().substring(pos);//得到文件名 try { tupian.transferTo(new File("D:\\date\\images\\bysj\\user\\"+fileName)); } catch (IOException e) { e.printStackTrace(); } url=pichost+"bysj/user/"+fileName; System.out.println(url); } return CommonResult.success(url); } /** * 添加/修改管理员 * @param manage * @return */ @RequestMapping("/manage/addManage") public CommonResult addManage(Manage manage){ Boolean aBoolean = manageService.addManage(manage); if (aBoolean){ return CommonResult.success("添加/修改管理员成功"); }else { return CommonResult.failed(); } } }
五,项目总结
本系统主要研究的课题是分析当下旅游业的发展瓶颈和影响人们旅游出行的因素,如何结合当今的IT行业技术解决当前人们旅游出行的存在的难点和需求,设计和实现基于面向用户服务的微服务系统。本系统使用企业级项目的开发模式,采用当前成熟的前后端分离开发,项目的架构是基于spring cloud微服务架构进行搭建的,根据用户量基数大、服务请求并发性高等特点,为达到系统的可用性和稳定性,采用搭建redis和mysql数据库系统,减轻系统数据库的压力,为企业级项目开发提供了解决思路。
本系统在企业级项目中,必须考虑系统的性能,系统的扩展性、高可用、高并发、系统的稳定性以及数据安全等需求,项目应该搭建数据库的集群,避免数据的丢失。项目应该采用分布式微服务的理念进行部署,采用集群和多服务器进行项目的上线,同时要设计合理的机制保证系统间服务的正常通信。由于本人在设计和实现过程中的资源和时间有限的情况下,无法满足这些需求。
现如今市面也有许多类似系统,能够承受庞大的访问请求,同时有pc端和移动端APP两种使用入口,这是比较好的。但是我查看过大部分的类似系统,发现各有优缺点,我这里总结一些它们存在的不足之处,如界面杂乱不美观,资讯和地方政策不能及时反馈给用户,用户存在感和分享感差,信息不够流通。希望今后能有一个比较好的系统能够解决这些问题,同时开发小程序入口,方便用户的使用。