SSM整合demo黑马旅游网-------5.旅游线路详细功能
1.功能分析
1.1 分页展示
- 点击不同的分类后,将来看到的旅游线路不一样
- 分页展示旅游线路数据
1.2 旅游线路详情

1.3 旅游线路收藏功能
- 判断当前登录用户是否收藏过该线路
- 根据标记,展示不同的按钮样式
- 收藏次数的动态展示
- 点击按钮收藏线路
2.分页展示功能
2.1 route_list.html
- 通过:location.search方法,获取 : ?cid=5 ,可以获得cid,即分类id
- 分页工具条数据展示
前台发送请求,携带参数:currentPage 当前页,pageSize 每页显示条数, cid:分类id
后台通过PageHelper分页工具类返回相应数据
展示总页码和总记录数
页码 十页,前5后4
- 数据展示
- 代码
<script>$(function () {var searching = location.search;// ?cid=5cid = searching.split("=")[1];//当页码加载完成后,调用load方法,发送ajax请求加载数据load(cid);});function load(cid, currentPage) {// 返回的是 pageBean对象的json数据$.get("/ssm-travel/route/routeByCid", {cid: cid,currentPage:currentPage}, function (data) {// *************************** 1.分页工具条数据展示 ********************************//1.1 展示总页码和总记录数$("#totalCount").html(data.total);$("#totalPage").html(data.pages);// 页码 十页,前5后4,/*1.一共展示10个页码,能够达到前5后4的效果2.如果前边不够5个,后边补齐10个3.如果后边不足4个,前边补齐10个class="curPage"*/var lis = "";var begin;var over;// 当前页 data.pageNum// 总页数 data.pages// 总页数 小于10, 开始页1,结束页就是总页数if (data.pages <= 10) {begin = 1;over = data.pages;} else {// 总页数 大于10, 开始页当前页减5,结束页当前页 + 4begin = data.pageNum - 5;over = begin + 9;// 当前页 小于 7,前面不足5,if (data.pageNum < 7) {begin = 1;over = begin + 9;} else {begin = data.pageNum - 5;over = data.pageNum + 4;}// 最后不足4 页, 结束页就是总页数,开始页 -9if (data.pages - data.pageNum < 4) {over = data.pages;begin = over - 9;}}// 首页var firstPage = ' + cid + ');">首页 ';lis += firstPage;//上一页 = data.currentPage -1var before;if (data.pageNum > 1) {before = data.pageNum - 1;} else {before = 1}console.log(before)console.log(data.pageNum)var beforePage = ' + cid + ',' + before + ')">上一页 ';lis += beforePage;for (var i = begin; i <= over; i++) {if (i == data.pageNum) {var li = ' + cid + ',' + i + ')">' + i + ' ';} else {var li = ' + cid + ',' + i + ')">' + i + ' ';}lis += li;}var next;if (data.pageNum != data.pages) {next = data.pageNum + 1;} else {next = data.pages;}//下一页var nextPage = ' + cid + ',' + next + ');">下一页 ';lis += nextPage;//末页var lastPage = ' + cid + ',' + data.pages + ');">末页 ';lis += lastPage;$("#fenye").html(lis);// *************************** 2. 数据展示 ********************************var lis2 = ''for (var i = 0; i < data.list.length; i++) {var li = '\n' +'
+ data.list[i].rimage + '">\n' +' \n' +' '
+ data.list[i].rname + '\n' +'
\n' +' '
+ data.list[i].routeIntroduce + '\n' +' \n' +' \n' +' \n'
+' ¥\n' +' ' + data.list[i].price + '\n' +' 起\n' +' \n' +' \n' +' \n' +' ';lis2 += li;}$("#shangpingxx").html(lis2);//定位到页面顶部window.scrollTo(0, 0);});}</script>
- 效果
具体含义见pageInfo里的内容

- 在相应路线展示和页面展示地方修改
<div class="left"><div class="header"><span>商品信息span><span class="jg">价格span>div><ul id="shangpingxx">
ul><div class="page_num_inf"><i>i> 共<span id="totalPage">span>页<span id="totalCount">span>条div><div class="pageNum"><ul id="fenye"><li><a href="">首页a>li><li class="threeword"><a href="#">上一页a>li><li class="curPage"><a href="#">1a>li><li><a href="#">2a>li><li><a href="#">3a>li><li><a href="#">4a>li><li><a href="#">5a>li><li><a href="#">6a>li><li><a href="#">7a>li><li><a href="#">8a>li><li><a href="#">9a>li><li><a href="#">10a>li><li class="threeword"><a href="javascript:;">下一页a>li><li class="threeword"><a href="javascript:;">末页a>li>ul>div>div>
- pageInfo里的内容
public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow 和endRow 不常用,这里说个具体的用法
//可以在页面中"显示startRow 到endRow 共size 条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
}
- 导入 PageHelper 坐标: pom.xml
<dependency><groupId>com.github.pagehelpergroupId><artifactId>pagehelperartifactId><version>5.1.2version>dependency>
- 配置applicationContext.xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:sqlMapConfig.xml"/><property name="plugins"><array><bean class="com.github.pagehelper.PageInterceptor"><property name="properties"><props><prop key="helperDialect">mysqlprop><prop key="reasonable">trueprop>props>property>bean>array>property>bean>
2.2 mapper层
- RouteListMapper.java
src\main\java\com\ssmtravel\mapper\RouteListMapper.java
package com.ssmtravel.mapper;import com.ssmtravel.domain.Route;import org.apache.ibatis.annotations.Select;import java.util.List;public interface RouteListMapper {@Select("select * from tab_route where cid = #{cid}")List<Route> selectRoute(int cid);}
2.3 service层
- RouteService.java接口
package com.ssmtravel.service;import com.ssmtravel.domain.Route;import java.util.List;public interface RouteService {List<Route> selectRoute(int cid);}
- 实现 RouteService.java
package com.ssmtravel.service.Impl;import com.ssmtravel.domain.Route;
import com.ssmtravel.mapper.RouteListMapper;
import com.ssmtravel.service.RouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service("routeService")
public class RouteServiceImpl implements RouteService {@Autowiredprivate RouteListMapper routeListMapper;@Overridepublic List<Route> selectRoute(int cid) {List<Route> routes = routeListMapper.selectRoute(cid);return routes;}
2.4 web层
- RouteListContorller.java
package com.ssmtravel.controller;import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssmtravel.domain.Route;
import com.ssmtravel.service.RouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;/*** @title: RouteListContorller * @Author Qian* @Date: 2022/4/14 16:09* @Version 1.0*/
@Controller
@RequestMapping("/route")
public class RouteListContorller {@Autowiredprivate RouteService routeService;// 1. 分类数据展示@RequestMapping(value = "/routeByCid",produces = "application/json;charset=utf-8")@ResponseBodypublic PageInfo<Route> routeByCid(String cid,String currentPage,String pageSize, HttpSession session) throws IOException {// 每页显示条数pageSize// 分类id cidint _currentPage = 0;int _pageSize = 0;int _cid = 0;// 处理参数// 如果不传递参数,则按默认参数调用查询if (currentPage != null && currentPage.length() > 0) {_currentPage = Integer.parseInt(currentPage);}else {_currentPage = 1;// 当前页面不传递则默认是第一页}if (pageSize != null && pageSize.length() > 0) {_pageSize = Integer.parseInt(pageSize);}else {_pageSize = 5;}if (cid != null && cid.length() > 0) {_cid = Integer.parseInt(cid);}/*不需要这句,一般 sql语句查询,limit限制查询条数后面有两个参数第一个参数是 起始条的 索引, 也就是第一条数据的索引,等于当前页 - 每页显示条数第二个参数是每页显示个数PageHelper.startPage(_currentPage, _pageSize);而 PageHelper.startPage 后面两个参数第一个是 第几页,比如第一页,第二页,不是第几页的第一条数据索引,谨记第二个参数是每页显示个数*/// 开始:(当前页 -1 ) * 显示条数// int start = (_currentPage- 1) * _pageSize;PageHelper.startPage(_currentPage, _pageSize);List<Route> routes = routeService.selectRoute(_cid);//其他分页的数据PageInfo<Route> pageInfo = new PageInfo<Route>(routes);return pageInfo;}}
一般 sql语句查询,limit限制查询条数后面有两个参数
第一个参数是 起始条的 索引, 也就是第一条数据的索引,等于当前页 - 每页显示条数
第二个参数是每页显示个数
PageHelper.startPage(_currentPage, _pageSize);
而 PageHelper.startPage 后面两个参数
第一个是 第几页,比如第一页,第二页,不是第几页的第一条数据索引,谨记
第二个参数是每页显示个数
分类分页展示功能完成。。。
3. 旅游线路详情
3.1 route_detail.html
-
当页面加载时,发送ajax请求传递rid(路线id)查询route对象
-
js代码
$(document).ready(function() {goImag();//自动播放// var timer = setInterval("auto_play()", 5000);});//自动轮播方法function auto_play() {var cur_index = $('.prosum_left dd').find('a.cur_img').index();cur_index = cur_index - 1;var num = $('.little_img').length;var max_index = 3;if ((num - 1) < 3) {max_index = num - 1;}if (cur_index < max_index) {var next_index = cur_index + 1;var big_pic = $('.little_img:eq(' + next_index + ')').data('bigpic');$('.little_img').removeClass('cur_img');$('.little_img:eq(' + next_index + ')').addClass('cur_img');$('.big_img').attr('src', big_pic);} else {var big_pic = $('.little_img:eq(0)').data('bigpic');$('.little_img').removeClass('cur_img');$('.little_img:eq(0)').addClass('cur_img');$('.big_img').attr('src', big_pic);}}searching = location.search;var rid = searching.split("=")[1];load(rid);/*favorite(rid);*/function load(rid) {$.get("/ssm-travel/routedetail/findRouteDetail", {rid: rid}, function (data) {console.log(data);$("#rname").html(data.rname);$("#routeIntroduce").html(data.routeIntroduce);$("#price").html("¥" + data.price);$("#sname").html(data.seller.sname);$("#consphone").html(data.seller.consphone);$("#address").html(data.seller.address);$("#shouceng").html("已收藏" + data.count + "次");console.log(data.routeImgList[0].bigPic)dtstr = '
+ data.routeImgList[0].bigPic + '">'$("#dtstr").html(dtstr);ddstr = '';for (var i = 0; i < data.routeImgList.length; i++) {if (i >= 4) {var astr = ' +' data-bigpic="' + data.routeImgList[i].bigPic + '"\n' +' >\n' +'
+ data.routeImgList[i].smallPic + '">\n' +' ';} else {var astr = ' +' data-bigpic="' + data.routeImgList[i].bigPic + '"\n' +' ">\n' +'
+ data.routeImgList[i].smallPic + '">\n' +' ';}ddstr += astr;}ddstr += ''$("#dd").html(ddstr)goImag();})}function goImag() {//焦点图效果//点击图片切换图片$('.little_img').on('mousemove', function () {$('.little_img').removeClass('cur_img');var big_pic = $(this).data('bigpic');$('.big_img').attr('src', big_pic);$(this).addClass('cur_img');});//上下切换var picindex = 0;var nextindex = 4;$('.down_img').on('click', function () {var num = $('.little_img').length;if ((nextindex + 1) <= num) {$('.little_img:eq(' + picindex + ')').hide();$('.little_img:eq(' + nextindex + ')').show();picindex = picindex + 1;nextindex = nextindex + 1;}});$('.up_img').on('click', function () {var num = $('.little_img').length;if (picindex > 0) {$('.little_img:eq(' + (nextindex - 1) + ')').hide();$('.little_img:eq(' + (picindex - 1) + ')').show();picindex = picindex - 1;nextindex = nextindex - 1;}});}
- html代码需要修改部分
<dt id="dtstr">
<dd id="dd"><div class="prosum_right"><p class="pros_title" id="rname">【尾单特卖】全国-曼谷6-7天自由行 泰国出境旅游 特价往返机票自由行二次确认p><p class="hot" id="routeIntroduce">1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!p><div class="pros_other"><p>经营商家 :<span id="sname">黑马国旅span>p><p>咨询电话 : <span id="consphone">400-618-9090span>p><p>地址 : <span id="address">传智播客黑马程序员span>p>div><div class="pros_price"><p class="price"><strong id="price">¥2699.00strong><span>起span>p><p class="collect"><a class="btn"><i class="glyphicon glyphicon-heart-empty">i>点击收藏a><a class="btn already" disabled="disabled"><i class="glyphicon glyphicon-heart-empty">i>点击收藏a><span id="shouceng">已收藏100次span>p>div> div>
3.2mapper层
- RouteDetailMapper.java
src\main\java\com\ssmtravel\mapper\RouteDetailMapper.java
package com.ssmtravel.mapper;import com.ssmtravel.domain.Route;
import com.ssmtravel.domain.RouteImg;
import com.ssmtravel.domain.Seller;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface RouteDetailMapper {// 查询路线详情@Select("select * from tab_route where rid=#{rid}")Route selectRoute(int rid);// 查询路线图片@Select("select * from tab_route_img where rid = #{rid}")List<RouteImg> selectRouteImg(int rid);// 查询商家@Select("select * from tab_seller where sid = #{sid}")Seller selectSeller(int sid);}
- FavoriteMapper.java
src\main\java\com\ssmtravel\mapper\FavoriteMapper.java
package com.ssmtravel.mapper;import org.apache.ibatis.annotations.Select;public interface FavoriteMapper {// 收藏次数@Select("select count(*) from tab_favorite where rid = #{rid}")int selectFavoCount(int rid);
}
3.3 service层
- RouteDetailService.jave 接口
package com.ssmtravel.service;import com.ssmtravel.domain.Route;
import com.ssmtravel.domain.RouteImg;
import com.ssmtravel.domain.Seller;import java.util.List;public interface RouteDetailService {Route selectRoute(int rid);List<RouteImg> selectRouteImg(int rid);Seller selectSeller(int sid);}
- FavoriteService.jave 接口
package com.ssmtravel.service;public interface FavoriteService {// 收藏次数int selectFavoCount(int rid);}
- 实现 RouteDetailServiceImpl.java
package com.ssmtravel.service.Impl;import com.ssmtravel.domain.Route;
import com.ssmtravel.domain.RouteImg;
import com.ssmtravel.domain.Seller;
import com.ssmtravel.mapper.RouteDetailMapper;
import com.ssmtravel.service.RouteDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service("routeDetailService")
public class RouteDetailServiceImpl implements RouteDetailService {@Autowiredprivate RouteDetailMapper routeDetailMapper;@Overridepublic Route selectRoute(int rid) {Route route = routeDetailMapper.selectRoute(rid);return route;}@Overridepublic List<RouteImg> selectRouteImg(int rid) {List<RouteImg> routeImgs = routeDetailMapper.selectRouteImg(rid);return routeImgs;}@Overridepublic Seller selectSeller(int sid) {Seller seller = routeDetailMapper.selectSeller(sid);return seller;}
}
- 实现 FavoriteServiceImpl.java
package com.ssmtravel.service.Impl;import com.ssmtravel.mapper.FavoriteMapper;
import com.ssmtravel.service.FavoriteService;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @title: FavoriteServiceImpl* @Author Qian* @Date: 2022/3/29 8:29* @Version 1.0*/
@Service("favoriteService")
public class FavoriteServiceImpl implements FavoriteService {@Autowiredprivate FavoriteMapper favoriteMapper;@Overridepublic int selectFavoCount(int rid) {int i = favoriteMapper.selectFavoCount(rid);return i;}
}
3.4 web层
- RouteDetailContorller.java
package com.ssmtravel.controller;import com.fasterxml.jackson.databind.ObjectMapper;
import com.ssmtravel.domain.Route;
import com.ssmtravel.domain.RouteImg;
import com.ssmtravel.domain.Seller;
import com.ssmtravel.service.FavoriteService;
import com.ssmtravel.service.RouteDetailService;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException;
import java.util.List;/*** @title: RouteDetailContorller* @Author Qian* @Date: 2022/4/14 16:09* @Version 1.0*/
@Controller
@RequestMapping("/routedetail")
public class RouteDetailContorller {@Autowiredprivate RouteDetailService routeDetailService;@Autowiredprivate FavoriteService favoriteService;// 1. 分类数据展示@RequestMapping(value = "/findRouteDetail",produces = "application/json;charset=utf-8")@ResponseBodypublic String findRouteDetail(String rid) throws IOException {int _rid = Integer.parseInt(rid);// 1. 查询route表Route route = routeDetailService.selectRoute(_rid);int sid = route.getSid();// 2. 查询 seller表Seller seller = routeDetailService.selectSeller(sid);route.setSeller(seller);// 3. 查询 rout_img表List<RouteImg> imgs = routeDetailService.selectRouteImg(_rid);route.setRouteImgList(imgs);// 4. 收藏次数int favoCount = favoriteService.selectFavoCount(_rid);route.setCount(favoCount);// 返回ObjectMapper objectMapper = new ObjectMapper();String s = objectMapper.writeValueAsString(route);return s;}}
旅游线路详情完成。。。。
4. 旅游线路收藏功能
4.1 route_detail.html
- 当页面加载完成发送ajax请求获取当前用户是否收藏的标记
- 根据标记展示不同收藏样式
- 点击收藏,判断用户是否登录
- 没有登录给出提示信息
- js代码
......
......
......
searching = location.search;
var rid = searching.split("=")[1];
load(rid);
favorite(rid); // 在这个位置添加这条,表示页面一刷新就判断用户是否收藏,展示不同画面
......
......//判断用户是否登录,展示不同样式function favorite(rid) {$.get("/ssm-travel/routedetail/isFavorite", {rid: rid}, function (data) {if (data != null) {// 表示已经收藏$("#isFavorite").addClass("already");$("#isFavorite").attr("disabled", "disabled");//删除按钮的点击事件$("#isFavorite").removeAttr("onclick");} else {// 表示未收藏}})}// 添加收藏function addFavorite() {searching = location.search;var rid = searching.split("=")[1];// 1. 先判断是否登录$.get("/ssm-travel/user/findName",{},function (data) {data = JSON.parse(data)if (data == "error"){//未登录alert("你暂未登录,请先登录")location.href = "/ssm-travel/login.html";}else {// 已登录// 添加收藏$.get("/ssm-travel/routedetail/addFavorite",{rid:rid},function (data) {//代码刷新页面location.reload();//定位到页面顶部window.scrollTo(0, 0);})}})}
- html代码需要修改部分
<p class="collect"><a class="btn" id="isFavorite" onclick="addFavorite();"><i class="glyphicon glyphicon-heart-empty">i>点击收藏a><span id="shouceng">已收藏100次span>p>
4.2mapper层
- FavoriteMapper.java
src\main\java\com\ssmtravel\mapper\FavoriteMapper.java
// 是否收藏@Select("select * from tab_favorite where rid = #{rid} and uid = #{uid}")Boolean Favorite(@Param("uid") int uid, @Param("rid") int rid);// 添加收藏@Insert("insert into tab_favorite (rid, date, uid) values (#{rid},now(),#{uid});")void addFavorite(@Param("rid") int rid,@Param("uid") int uid);
4.3 service层
- FavoriteService.jave 接口
Boolean Favorite(int uid, int rid);void addFavorite(int rid, int uid);
- 实现 RouteDetailServiceImpl.java
@Overridepublic Boolean Favorite(int uid, int rid) {// 收藏Boolean favorite = favoriteMapper.Favorite(uid, rid);return favorite;}@Overridepublic void addFavorite(int rid, int uid) {favoriteMapper.addFavorite(rid,uid);}
4.4 web层
- RouteDetailContorller.java
// 判断是否已经收藏过@RequestMapping(value = "/isFavorite", produces = "application/json;charset=utf-8")@ResponseBodypublic String isFavorite(String rid, HttpSession session) throws JsonProcessingException {int _rid = Integer.parseInt(rid);User user = (User) session.getAttribute("user");int uid;if (user == null) {uid = 0;} else {uid = user.getUid();}Boolean favorite = favoriteService.Favorite(uid, _rid);ObjectMapper objectMapper = new ObjectMapper();return objectMapper.writeValueAsString(favorite);}// 添加收藏@RequestMapping(value = "/addFavorite", produces = "application/json;charset=utf-8")@ResponseBodypublic String addFavorite(String rid, HttpSession session) throws JsonProcessingException {int _rid = Integer.parseInt(rid);User user = (User) session.getAttribute("user");int uid = user.getUid();favoriteService.addFavorite(_rid, uid);ObjectMapper objectMapper = new ObjectMapper();return objectMapper.writeValueAsString("success");}
项目基本完成。。。。。其余功能有兴趣自行开发。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
