目录
一、分析表关系
线路表与收藏表是: 一对多关系
用户表与收藏表是: 一对多关系
当页面加载完成后,发送ajax请求,获取用户是否收藏的标记
根据标记,展示不同的按钮样式
二、收藏线路前端实现
route_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>路线详情</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/route-detail.css">
<script src="js/jquery-3.3.1.js"></script>
<script src="js/getParameter.js"></script>
</head>
<body>
<!--引入头部-->
<div id="header"></div>
<!-- 详情 start -->
<div class="wrap">
<div class="bread_box">
<a href="/">首页</a>
<span> ></span>
<a href="#">国内游</a><span> ></span>
<a href="#">全国-曼谷6-7天自由行 泰国出境旅游 特价往返机票自由行二次确认</a>
</div>
<div class="prosum_box">
<dl class="prosum_left">
<dt>
<img alt="" class="big_img" src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m49788843d72171643297ccc033d9288ee.jpg">
</dt>
<dd id="ddString">
</dd>
</dl>
<div class="prosum_right">
<p id="pros_title" class="pros_title"></p>
<p id="hot" class="hot"></p>
<div class="pros_other">
<p>经营商家 :<span id="seller_name"></span></p>
<p>咨询电话 : <span id="phone_number"></span></p>
<p>地址 : <span id="address"></span></p>
</div>
<div class="pros_price">
<p id="price" class="price"><strong>¥2699.00</strong><span>起</span></p>
<p class="collect">
<a id="favorite" class="btn"><i class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>
<span id="favoritecount">已收藏100次</span>
</p>
</div>
</div>
</div>
<div class="you_need_konw">
<span>旅游须知</span>
<div class="notice">
<p>1、旅行社已投保旅行社责任险。建议游客购买旅游意外保险 <br>
<p>2、旅游者参加打猎、潜水、海边游泳、漂流、滑水、滑雪、滑草、蹦极、跳伞、滑翔、乘热气球、骑马、赛车、攀岩、水疗、水上飞机等属于高风险性游乐项目的,敬请旅游者务必在参加前充分了解项目的安全须知并确保身体状况能适应此类活动;如旅游者不具备较好的身体条件及技能,可能会造成身体伤害。</p>
<p>3、参加出海活动时,请务必穿着救生设备。参加水上活动应注意自己的身体状况,有心脏病、冠心病、高血压、感冒、发烧和饮酒及餐后不可以参加水上活动及潜水。在海里活动时,严禁触摸海洋中各种鱼类,水母,海胆,珊瑚等海洋生物,避免被其蛰伤。老人和小孩必须有成年人陪同才能参加合适的水上活动。在海边游玩时,注意保管好随身携带的贵重物品。</p>
<p>4、根据中国海关总署的规定,旅客在境外购买的物品,在进入中国海关时可能需要征收关税。详细内容见《中华人民共和国海关总署公告2010年第54号文件》。</p>
<p>5、建议出发时行李托运,贵重物品、常用物品、常用药品、御寒衣物等请随身携带,尽量不要托运。行李延误属于不可抗力因素,我司将全力协助客人跟进后续工作,但我司对此不承担任何责任。</p>
<p>1、旅行社已投保旅行社责任险。建议游客购买旅游意外保险 <br>
<p>2、旅游者参加打猎、潜水、海边游泳、漂流、滑水、滑雪、滑草、蹦极、跳伞、滑翔、乘热气球、骑马、赛车、攀岩、水疗、水上飞机等属于高风险性游乐项目的,敬请旅游者务必在参加前充分了解项目的安全须知并确保身体状况能适应此类活动;如旅游者不具备较好的身体条件及技能,可能会造成身体伤害。</p>
<p>3、参加出海活动时,请务必穿着救生设备。参加水上活动应注意自己的身体状况,有心脏病、冠心病、高血压、感冒、发烧和饮酒及餐后不可以参加水上活动及潜水。在海里活动时,严禁触摸海洋中各种鱼类,水母,海胆,珊瑚等海洋生物,避免被其蛰伤。老人和小孩必须有成年人陪同才能参加合适的水上活动。在海边游玩时,注意保管好随身携带的贵重物品。</p>
<p>4、根据中国海关总署的规定,旅客在境外购买的物品,在进入中国海关时可能需要征收关税。详细内容见《中华人民共和国海关总署公告2010年第54号文件》。</p>
<p>5、建议出发时行李托运,贵重物品、常用物品、常用药品、御寒衣物等请随身携带,尽量不要托运。行李延误属于不可抗力因素,我司将全力协助客人跟进后续工作,但我司对此不承担任何责任。</p>
</div>
</div>
</div>
<!-- 详情 end -->
<!--引入头部-->
<div id="footer"></div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="js/jquery-3.3.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<!--导入布局js,共享header和footer-->
<script type="text/javascript" src="js/include.js"></script>
<script>
$(document).ready(function() {
goImg();
//自动播放
// var timer = setInterval("auto_play()", 5000);
});
function goImg(){
//焦点图效果
//点击图片切换图片
$('.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;
}
});
}
//自动轮播方法
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);
}
}
//实现加载路线详情
$(function () {
// <dd>
// <a class="up_img up_img_disable"></a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m40920d0669855e745d97f9ad1df966ebb.jpg">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m20920d0669855e745d97f9ad1df966ebb.jpg">
// </a>
// <a title="" class="little_img cur_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m49788843d72171643297ccc033d9288ee.jpg">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m29788843d72171643297ccc033d9288ee.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m4531a8dbceefa2c44e6d0e35627cd2689.jpg">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m2531a8dbceefa2c44e6d0e35627cd2689.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m46d8cb900e9f6c0a762aca19eae40c00c.jpg">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m26d8cb900e9f6c0a762aca19eae40c00c.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m45ea00f6eba562a767b5095bbf8cffe07.jpg" style="display:none;">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m25ea00f6eba562a767b5095bbf8cffe07.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m4265ec488cd1bc7ce749bc8c9b34b87bc.jpg" style="display:none;">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m2265ec488cd1bc7ce749bc8c9b34b87bc.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m4e7e964909d7dd1a9f6e5494d4dc0c847.jpg" style="display:none;">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m2e7e964909d7dd1a9f6e5494d4dc0c847.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m467db00e1b76718fab0fe8b96e10f4d35.jpg" style="display:none;">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m267db00e1b76718fab0fe8b96e10f4d35.jpg">
// </a>
// <a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m487bbbc6e43eba6aa6a36cc1a182f7a20.jpg" style="display:none;">
// <img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m287bbbc6e43eba6aa6a36cc1a182f7a20.jpg">
// </a>
// <a class="down_img down_img_disable" style="margin-bottom: 0;"></a>
// </dd>
var rid=getParameter("rid");
//通过异步获取route信息
$.get("route/queryOne",{rid:rid},function (route) {
$("#pros_title").html(route.rname);
$("#hot").html(route.routeIntroduce);
$("#price").html("¥"+route.price);
$("#seller_name").html(route.seller.sname);
$("#phone_number").html(route.seller.consphone);
$("#address").html(route.seller.address);
$("#favoritecount").html("已收藏"+route.count+"次");
//图片信息
var ddstr = ' <a class="up_img up_img_disable"></a>';
//遍历图片集合
for(var i=0;i<route.routeImgList.length;i++){
/**
<a title="" class="little_img" data-bigpic="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size4/201703/m40920d0669855e745d97f9ad1df966ebb.jpg">
<img src="http://www.jinmalvyou.com/Public/uploads/goods_img/img_size2/201703/m20920d0669855e745d97f9ad1df966ebb.jpg">
</a>
*/
var astr="";
if (i>=4){
//图片超出展示
astr='<a title="" class="little_img" style="display:none;" data-bigpic="'+route.routeImgList[i].bigPic+'">\n' +
' <img src="'+route.routeImgList[i].smallPic+'">\n' +
' </a>';
}else {
astr='<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'">\n' +
' <img src="'+route.routeImgList[i].smallPic+'">\n' +
' </a>';
}
ddstr+=astr;
}
ddstr+='<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';
$("#ddString").html(ddstr);
goImg();
});
});
//判断用户是否收藏
$(function () {
var rid = getParameter("rid");
$.get("route/isFavourite",{rid:rid},function (flag) {
if (flag){
//已收藏 设置css样式
$("#favorite").addClass("already");
//$("#favorite").attr("disabled","disabled");
//取消绑定的事件
$("#favorite").removeAttr("onclick");
}else{
//未收藏
}
});
});
//添加收藏
$(function () {
var rid = getParameter("rid");
$("#favorite").click(function () {
//判断用户是否登录
$.get("user/findUser",{},function (user) {
if (user){
//已登录
$.get("route/addFavourite",{rid:rid},function () {
//刷新页面
location.reload();
});
}else{
//没登录
alert("您尚未登录,请登录!");
location.href="http://localhost/travel/login.html";
}
});
});
});
</script>
</body>
</html>
三、收藏线路后端实现
RouteServlet
package com.hotdas.travel.web.servlet;
import com.hotdas.travel.domain.PageBean;
import com.hotdas.travel.domain.Route;
import com.hotdas.travel.domain.User;
import com.hotdas.travel.service.FavoriteService;
import com.hotdas.travel.service.RouteService;
import com.hotdas.travel.service.impl.FavoriteServiceImpl;
import com.hotdas.travel.service.impl.RouteServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {
private RouteService routeService = new RouteServiceImpl();
private FavoriteService favoriteService = new FavoriteServiceImpl();
public void queryPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException,Exception {
//接收参数
String currentPageStr = request.getParameter("currentPage");
String cidStr = request.getParameter("cid");
String pageSizeStr = request.getParameter("pageSize");
System.out.println("cid="+cidStr);
//有可能通过线路名称查询
String rnameStr = request.getParameter("rname");
rnameStr=new String(rnameStr.getBytes("iso-8859-1"),"utf-8");
System.out.println("rname="+rnameStr);
//判断cid
int cid =0;
if(cidStr!=null && cidStr.length()>0 && !"null".equals(cidStr)){
cid=Integer.parseInt(cidStr);
}
int currentPage=1;
if(currentPageStr!=null && currentPageStr.length()>0){
currentPage=Integer.parseInt(currentPageStr);
}else{
currentPage=1;
}
int pageSize = 0;
if(pageSizeStr!=null && pageSizeStr.length()>0){
pageSize=Integer.parseInt(pageSizeStr);
}else{
pageSize=5;
}
//调用service查询数据
PageBean<Route> pageBean = routeService.queryPage(cid,currentPage,pageSize,rnameStr);
writeValue(pageBean,response);
}
//查询路线详情信息
public void queryOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException,Exception {
System.out.println("queryOne is running ...");
//获取rid
String rid = request.getParameter("rid");
//调用service查询路线的详情信息
Route route = routeService.findOne(rid);
//转化为json返回客户端
writeValue(route,response);
}
//添加收藏
public void addFavourite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException,Exception {
//1.获取路线rid
String rid = request.getParameter("rid");
//2.从session中获取用户
User user = (User)request.getSession().getAttribute("user");
int uid ;//当前登录用户的uid;
//判断用户是否登录
if (user==null){
//没有登录
return;
}else{
//用户已登录
uid = user.getUid();
}
//3.调用service收藏线路
favoriteService.add(rid,uid);
}
//判断用户是否收藏
public void isFavourite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException,Exception {
//1.获取rid
String rid = request.getParameter("rid");
//2.获取当前登录的用户
User user = (User)request.getSession().getAttribute("user");
int uid ;//当前登录用户的uid;
//判断用户是否登录
if (user==null){
//没有登录
return;
}else{
//用户已登录
uid = user.getUid();
}
//3得到是否收藏
Boolean flag = favoriteService.isFavourite(rid,uid);
//4.写入客户端
writeValue(flag,response);
}
}
FavoriteServiceImpl
package com.hotdas.travel.service.impl;
import com.hotdas.travel.dao.FavoriteDao;
import com.hotdas.travel.dao.RouteDao;
import com.hotdas.travel.dao.impl.FavoriteDaoImpl;
import com.hotdas.travel.dao.impl.RouteDaoImpl;
import com.hotdas.travel.domain.Favorite;
import com.hotdas.travel.service.FavoriteService;
public class FavoriteServiceImpl implements FavoriteService {
private FavoriteDao favoriteDao =new FavoriteDaoImpl();
private RouteDao routeDao = new RouteDaoImpl();
@Override
public void add(String rid, int uid) {
favoriteDao.add(rid,uid);
int count = favoriteDao.findFavoriteCount(rid);
routeDao.updateFavoriteCount(rid,count);
}
@Override
public Boolean isFavourite(String rid, int uid) {
Favorite favorite = favoriteDao.findFavouriteByRidAndUid(rid,uid);
Boolean flag=false;
if (favorite!=null){
flag = true;
}else{
flag=false;
}
return flag;
}
}
FavoriteService
package com.hotdas.travel.service;
public interface FavoriteService {
void add(String rid, int uid);
Boolean isFavourite(String rid, int uid);
}
FavoriteDaoImpl
package com.hotdas.travel.dao.impl;
import com.hotdas.travel.dao.FavoriteDao;
import com.hotdas.travel.domain.Favorite;
import com.hotdas.travel.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.Date;
public class FavoriteDaoImpl implements FavoriteDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public void add(String rid, int uid) {
String sql ="insert into tab_favorite values(?,?,?)";
template.update(sql,rid,new Date(),uid);
}
@Override
public Favorite findFavouriteByRidAndUid(String rid, int uid) {
String sql = "select * from tab_favorite where rid=? and uid=?";
Favorite favorite = template.queryForObject(sql,new BeanPropertyRowMapper<Favorite>(Favorite.class),rid,uid);
return favorite;
}
//收藏量
@Override
public int findFavoriteCount(String rid) {
String sql = "select count(*) from tab_favorite where rid=?";
int count = template.queryForObject(sql,Integer.class,rid);
return count;
}
}
FavoriteDao
package com.hotdas.travel.dao;
import com.hotdas.travel.domain.Favorite;
public interface FavoriteDao {
void add(String rid, int uid);
Favorite findFavouriteByRidAndUid(String rid, int uid);
int findFavoriteCount(String rid);
}
四、测试
1.打开收藏页面,点击收藏页面,点击成功显示收藏一次