黑马旅游网编写练习(10)–用户收藏线路的展示功能
分析
当用户点击我的收藏按钮时,需要将用户所收藏的所有线路进行展示;并且点击响应的线路,就会跳转到该线路对应的详情页面。
旅游线路的分页展示功能之前已经进行了实现,此处只需要仿照该方法,将查询的表格修改为tab_favorite即可;
跳转到路线详情页面之前也进行过实现,此处也只需要仿照该处传递相应的参数即可。
首先完成’我的收藏’按钮的跳转功能
此处需要要展示的页面是根据当前登录的,所以首先查询用户是否登录;若未登录,则弹出未登陆提示,然后跳转到登陆页面;若用户已登录,则跳转到favoriterank.html页面。具体代码如下:
// 点击我的收藏按钮调用此函数
function myFavorite() {
// 访问user/helloUser查询用户是否登录
$.post("user/helloUser",{},function (user) {
if(user != null){
// 用户已经登陆
// 传递到favoriterank.html页面
location.href="http://localhost/travel/favoriterank.html";
}else{
// 用户尚未登陆
alert("您尚未登录,请先登录");
// 跳转到登陆页面
location.href="http://localhost/travel/login.html";
}
});
}
然后在favoriterank.html页面向服务器发送请求进行查询
请求查询代码如下,此处还未编写查询结果的展示代码,结果的展示在查询后台代码完成后再进行编写。此处代码目前为:
$(function () {
// 调用load函数向服务器发送Ajax请求获取页面数据
load();
});
function load(currentPage) {
// 向服务器发送Ajax请求获取页面数据
$.post("route/myFavorite",{currentPage:currentPage},function (data) {
}
}
接下来编写后台查询代码
由于收藏的路线和用户相关,所以便将查询我的收藏功能在UserServlet中进行实现。在其中添加一个myFavorite方法,该方法的主要内容如下:
/**
* 查询用户收藏的所有旅游线路
* @param request
* @param response
* @throws IOException
*/
public void myFavorite(HttpServletRequest request, HttpServletResponse response) throws IOException{
// 获取当前登录用户
User user = (User) request.getSession().getAttribute("user");
if(user == null || "".equals(user)){
// 用户未登录,请求错误
System.out.println("用户未登录,收藏线路请求错误");
return;
}
// 接收当前页码
String currentPage_str = request.getParameter("currentPage");
if(currentPage_str == null || currentPage_str.length() == 0){
// currentPage为空,设置默认值为1,访问首页
currentPage_str = "1";
}
int currentPage = Integer.parseInt(currentPage_str);
// 调用favoriteService中方法查询用户收藏的所有旅游线路,返回一个PageBean对象
PageBean<Favorite> pageBean = favoriteService.myFavorite(user, currentPage);
// 将pageBean对象序列化为json并响应给客户端
responseJson(response,pageBean);
}
service层首先需要调用favoriteDao中查询总线路条数,计算总页面数;然后调用favoriteDao层查询该用户所有收藏的线路信息,将其封装到favorite对象中,得到一个list集合;然后需要遍历集合,对每一个favorite对象,分别设置其路线的详细信息,路线的信息首先要调用RouteDao中通过rid查询tab_route表的方法,然后需要再调用favoriteDao查询tab_favorite表中该路线被收藏次数。最后封装pageBean对象返回。主要代码如下:
/**
* 查询用户的所有收藏线路,响应pageBean对象给客户端
* @param user
* @param currentPage
* @return
*/
@Override
public PageBean<Favorite> myFavorite(User user, int currentPage, int pageSize) {
System.out.println("FavoriteService收到的currentPage:"+ currentPage);
// 定义PageBean对象
PageBean<Favorite> pageBean = new PageBean<Favorite>();
// 调用favoriteDao中查询总线路条数
int totalCount = favoriteDao.findTotalCountByUid(user.getUid());
// 计算总页面数
int totalPage = (totalCount % pageSize == 0)?(totalCount / pageSize):(totalCount / pageSize + 1);
// 计算开始查询位置
int start = (currentPage - 1) * pageSize;
// 通过favoriteDao调用uid查询tab_favorite表,返回list集合
List<Favorite> list = favoriteDao.findByUid(user.getUid(),start,pageSize);
// 遍历集合;
Route route; // 定义旅游路线对象
for (Favorite favorite : list) {
// 调用RouteDao中通过rid查询tab_route表
route = routeDao.findRouteByRid(favorite.getRid());
// 调用favoriteDao查询tab_favorite表中该路线被收藏次数
route.setCount(favoriteDao.findByRid(favorite.getRid()));
// 查询结果赋值给route对象
favorite.setRoute(route);
}
// 封装pageBean对象
pageBean.setTotalCount(totalCount);
pageBean.setTotalPage(totalPage);
pageBean.setCurrentPage(currentPage);
pageBean.setPageSize(pageSize);
pageBean.setList(list);
return pageBean;
}
dao层需要编写的方法有两个,一个是favoriteDao中查询总线路条数方法;另一个是favoriteDao层查询该用户收藏的线路信息方法注意,并不是查询所有,而是查询指定数目的线路信息;这两个方法内容分别如下所示:
/**
* 通过用户uid查询favorite表,将内容封装到list集合中
* @param uid
* @return
*/
@Override
public List<Favorite> findByUid(int uid, int start, int pageSize) {
String sql = "select * from tab_favorite where uid = ? limit ? ,? ";
List<Favorite> list = template.query(sql, new BeanPropertyRowMapper<Favorite>(Favorite.class), uid,start,pageSize);
return list;
}
/**
* 查询用户共收藏线路条数
* @param uid
* @return
*/
@Override
public int findTotalCountByUid(int uid) {
// 定义sql
String sql = "select count(*) from tab_favorite where uid = ?";
return template.queryForObject(sql,Integer.class,uid);
}
至此,已经完成了后台代码的编写。接下来需要在前台将响应的json数据填充到相应的位置即可。
前台收藏线路的填充
这部分工作与之前的黑马旅游网编写练习(6)旅游线路分页展示功能基本一致,具体可参考该处文章;此处不再详细讲解;直接给出实现代码,如下:
function load(currentPage) {
// 向服务器发送Ajax请求获取页面数据
$.post("user/myFavorite",{currentPage:currentPage},function (pageBean) {
var routes = pageBean.list;
// 展示共多少页,共多少条记录
$("#totalCount").html(pageBean.totalCount);
$("#totalPage").html(pageBean.totalPage);
// 展示路线
var rou_str;
for (var i = 0; i < routes.length; i++) {
var li = ' <li>\n' +
' <span class="num one">'+(i+1)+'</span>\n' +
' <a href="route_detail.html"><img src="'+routes[i].route.rimage+'" alt=""></a>\n' +
' <h4><a href="route_detail.html">'+routes[i].route.rname+'</a></h4>\n' +
' <p>\n' +
' <b class="price">¥<span>'+routes[i].route.price+'</span>起</b>\n' +
' <span class="shouchang">已收藏'+routes[i].route.count+'次</span>\n' +
' </p>\n' +
' </li>';
rou_str += li;
}
$("#route").html(rou_str);
// 展示页码工具条,实现前5后4的效果
var beforeNum = pageBean.currentPage - 1;
if(beforeNum <= 0){
beforeNum = 1;
}
// 拼接首页和上一页
var lis = '<li οnclick="javascript:load(1)"><a href="javascript:void(0);">首页</a></li>\n' +
' <li οnclick="javascript:load('+beforeNum+')" class="threeword"><a href="javascript:void(0);">上一页</a></li>';
var beginNum = pageBean.currentPage - 5;
var endNum = pageBean.currentPage + 4;
if(beginNum <= 0){
beginNum = 1;
endNum = beginNum + 9;
}
if(endNum > pageBean.totalPage){
endNum = pageBean.totalPage;
beginNum = endNum - 9;
}
// 若总页面不足10页
if(pageBean.totalPage < 10){
beginNum = 1;
endNum = pageBean.totalPage;
}
for (var i = beginNum; i <= endNum; i++) {
var li = ' <li οnclick="javascript:load('+i+')"><a href="javascript:void(0);">'+i+'</a></li>';
lis += li;
}
// 设置下一页
var nextNum = pageBean.currentPage + 1;
if(nextNum > pageBean.totalPage){
nextNum = pageBean.totalPage;
}
lis += ' <li οnclick="javascript:load('+nextNum+')" class="threeword"><a href="javascript:void(0);">下一页</a></li>\n' +
' <li οnclick="javascript:load('+pageBean.totalPage+')" class="threeword"><a href="javascript:void(0);">末页</a></li>';
$("#page").html(lis);
});
}
最后还差一个,点击收藏线路的标题,或者图片,能够跳转到该线路的详情页面
该功能也与黑马旅游网编写练习(6)旅游线路分页展示功能中的查案详情处基本相似;因为此处也是要跳转到route_detail.html页面;所以需要传递的参数以及路径都是一致的;分别为图片和标题添加如下所示的路径即可。
// 展示路线
var rou_str;
for (var i = 0; i < routes.length; i++) {
var li = ' <li>\n' +
' <span class="num one">'+(i+1)+'</span>\n' +
' <a href="route_detail.html?rid='+routes[i].route.rid+'"><img src="'+routes[i].route.rimage+'" alt=""></a>\n' +
' <h4><a href="route_detail.html?rid='+routes[i].route.rid+'">'+routes[i].route.rname+'</a></h4>\n' +
' <p>\n' +
' <b class="price">¥<span>'+routes[i].route.price+'</span>起</b>\n' +
' <span class="shouchang">已收藏'+routes[i].route.count+'次</span>\n' +
' </p>\n' +
' </li>';
rou_str += li;
}
至此,用户的旅游路线的收藏功能便已实现完毕。