• 旅游网项目4


    12.旅游线路收藏功能

    12.1分析:旅游线路收藏功能

    当页面加载完成后,发送ajax请求,获取用户是否收藏的标记

    根据标记,展示不同的按钮样式

    12.2后台代码

    RouteServlet

    package cn.itcast.travel.web.servlet;
    
    import cn.itcast.travel.domain.PageBean;
    import cn.itcast.travel.domain.Route;
    import cn.itcast.travel.domain.User;
    import cn.itcast.travel.service.FavoriteService;
    import cn.itcast.travel.service.RouteService;
    import cn.itcast.travel.service.impl.FavoriteServiceImpl;
    import cn.itcast.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 pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.接受参数
            String currentPageStr = request.getParameter("currentPage");
            String pageSizeStr = request.getParameter("pageSize");
            String cidStr = request.getParameter("cid");
            //接受rname路线名称
            String rname = request.getParameter("rname");
            rname = new String(rname.getBytes("iso-8859-1"),"utf-8");
    
            //2.处理参数
            int cid = 0;//类别id
            if(cidStr != null && cidStr.length() > 0 && !"null".equals(cidStr)){
                cid = Integer.parseInt(cidStr);
            }
    
            int currentPage = 0;//当前页码,默认为第一页
            if (currentPageStr != null && currentPageStr.length() > 0) {
                currentPage = Integer.parseInt(currentPageStr);
            } else {
                currentPage = 1;
            }
    
            int pageSize = 0;//每页显示条数,默认显示5条
            if (pageSizeStr != null && pageSizeStr.length() > 0) {
                pageSize = Integer.parseInt(pageSizeStr);
            } else {
                pageSize = 5;
            }
    
            //3. 调用service查询PageBean对象
            PageBean<Route> pb = routeService.pageQuery(cid, currentPage, pageSize,rname);
    
            //4. 将pageBean对象序列化为json,返回
            writeValue(pb, response);
        }
    
        /*
        根据id查询一个旅游线路的详细信息
         */
        public void findOne(HttpServletRequest request,HttpServletResponse response) throws IOException {
            //1.接收id
            String rid = request.getParameter("rid");
            //2.调用service查询route对象
            Route route = routeService.findOne(rid);
            //转为json写入客户端
            writeValue(route,response);
        }
    
        /*
        判断当前用户是否收藏过该线路
         */
        public void isFavorite(HttpServletRequest request,HttpServletResponse response) throws IOException {
            //1.获取线路id
            String rid = request.getParameter("rid");
    
            //2.获取当前登录的用户user
            User user = (User) request.getSession().getAttribute("user");
            int uid;//用户的id
            if(user==null){
                //用户尚未登录
                uid = 0;
            }else {
                //用户已经登录
                uid=user.getUid();
            }
    
            //3.调用FavoriteService查询是否收藏
            //3. 调用FavoriteService查询是否收藏
            boolean flag = favoriteService.isFavorite(rid, uid);
    
            //4. 写回客户端
            writeValue(flag,response);
    
        }
    
    
    }

    FavoriteService

    package cn.itcast.travel.service;
    
    public interface FavoriteService {
    
        /**
         * 判断是否收藏
         */
         boolean isFavorite(String rid, int uid);
    }
    package cn.itcast.travel.service.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.dao.impl.FavoriteDaoImpl;
    import cn.itcast.travel.domain.Favorite;
    import cn.itcast.travel.service.FavoriteService;
    
    public class FavoriteServiceImpl implements FavoriteService {
    
        private FavoriteDao favoriteDao = new FavoriteDaoImpl();
    
        @Override
        public boolean isFavorite(String rid, int uid) {
    
            Favorite favorite = favoriteDao.findByRidAndUid(Integer.parseInt(rid), uid);
    
            return favorite != null;//如果对象有值,则为true,反之,则为false
        }
    }

    FavoriteDao

    package cn.itcast.travel.dao;
    
    import cn.itcast.travel.domain.Favorite;
    
    public interface FavoriteDao {
    
        /**
         * 根据rid和uid查询收藏信息
         */
         Favorite findByRidAndUid(int rid, int uid);
    
    }
    package cn.itcast.travel.dao.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.domain.Favorite;
    import cn.itcast.travel.util.JDBCUtils;
    import org.springframework.dao.DataAccessException;
    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 Favorite findByRidAndUid(int rid, int uid) {
            Favorite favorite = null;
            try {
                String sql = " select * from tab_favorite where rid = ? and uid = ?";
                favorite = template.queryForObject(sql, new BeanPropertyRowMapper<Favorite>(Favorite.class), rid, uid);
            } catch (DataAccessException e) {
                e.printStackTrace();
            }
            return favorite;
        }
    
    }

    12.3前台代码

    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">
    
    </head>
    
    <body>
    <!--引入头部-->
    <div id="header"></div>
    <!-- 详情 start -->
    <div class="wrap">
        <div class="bread_box">
            <a href="/">首页</a>
            <span> &gt;</span>
            <a href="#">国内游</a><span> &gt;</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="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>
            </dl>
            <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-9090</span></p>
                    <p>地址 : <span id="address">传智播客黑马程序员</span></p>
                </div>
                <div class="pros_price">
                    <p class="price"><strong id="price">¥2699.00</strong><span></span></p>
                    <p class="collect">
                        <a class="btn" id="favorite" onclick="addFavorite();"><i class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>
    
                        <!--<a class="btn already" disabled="disabled"><i class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>-->
                        <span>已收藏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>
    
    <script src="js/getParameter.js"></script>
    
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    <script>
        $(document).ready(function () {
        goImg();
        });
        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 () {
            //1.获取id
            var rid = getParameter("rid");
            //2.发送请求请求 route/findOne
            $.get("route/findOne", {rid: rid}, function (route) {
                //3.解析数据填充html
                $("#rname").html(route.rname);
                $("#routeIntroduce").html(route.routeIntroduce);
                $("#price").html("¥"+route.price);
                $("#sname").html(route.seller.sname);
                $("#consphone").html(route.seller.consphone);
                $("#address").html(route.seller.address);
                //图片展示
    
                var ddstr = '<a class="up_img up_img_disable"></a>';
    
                //遍历routeImgList
                for (var i = 0; i < route.routeImgList.length; i++) {
                    var astr ;
                    if(i >= 4){
                        astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" style="display:none;">
    ' +
                            '                        <img src="'+route.routeImgList[i].smallPic+'">
    ' +
                            '                    </a>';
                    }else{
                        astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'">
    ' +
                            '                        <img src="'+route.routeImgList[i].smallPic+'">
    ' +
                            '                    </a>';
                    }
    
    
                    ddstr += astr;
                }
                ddstr+='<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';
    
                $("#dd").html(ddstr);
    
                //图片展示和切换代码调用
                goImg();
            });
        })
        $(function () {
            // 发送请求,判断用户是否收藏过该线路
            var rid = getParameter("rid");
            $.get("route/isFavorite",{rid:rid},function (flag) {
                if(flag){
                    // 用户已经收藏过
                    //<a  class="btn already" disabled="disabled">
                    //设置收藏按钮的样式
                    $("#favorite").addClass("already");
                    $("#favorite").attr("disabled","disabled");
    
                }else{
                    // 用户没有收藏
                }
            });
        });
    
    </script>
    </body>
    
    </html>

    12.4收藏次数的动态展示

    前台

     $(function () {
            //1.获取id
            var rid = getParameter("rid");
            //2.发送请求请求 route/findOne
            $.get("route/findOne", {rid: rid}, function (route) {
                //3.解析数据填充html
                $("#rname").html(route.rname);
                $("#routeIntroduce").html(route.routeIntroduce);
                $("#price").html("¥"+route.price);
                $("#sname").html(route.seller.sname);
                $("#consphone").html(route.seller.consphone);
                $("#address").html(route.seller.address);
                //设置收藏次数
                $("#favoriteCount").html("已收藏"+route.count+"次");
                //图片展示
    
                var ddstr = '<a class="up_img up_img_disable"></a>';
    
                //遍历routeImgList
                for (var i = 0; i < route.routeImgList.length; i++) {
                    var astr ;
                    if(i >= 4){
                        astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" style="display:none;">
    ' +
                            '                        <img src="'+route.routeImgList[i].smallPic+'">
    ' +
                            '                    </a>';
                    }else{
                        astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'">
    ' +
                            '                        <img src="'+route.routeImgList[i].smallPic+'">
    ' +
                            '                    </a>';
                    }
    
    
                    ddstr += astr;
                }
                ddstr+='<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';
    
                $("#dd").html(ddstr);
    
                //图片展示和切换代码调用
                goImg();
            });
        })

    后台:

             RouteService

    package cn.itcast.travel.service.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.dao.RouteDao;
    import cn.itcast.travel.dao.RouteImgDao;
    import cn.itcast.travel.dao.SellerDao;
    import cn.itcast.travel.dao.impl.FavoriteDaoImpl;
    import cn.itcast.travel.dao.impl.RouteDaoImpl;
    import cn.itcast.travel.dao.impl.RouteImgDaoImpl;
    import cn.itcast.travel.dao.impl.SellerDaoImpl;
    import cn.itcast.travel.domain.PageBean;
    import cn.itcast.travel.domain.Route;
    import cn.itcast.travel.domain.RouteImg;
    import cn.itcast.travel.domain.Seller;
    import cn.itcast.travel.service.RouteService;
    
    import java.util.List;
    
    public class RouteServiceImpl implements RouteService {
        private RouteDao routeDao = new RouteDaoImpl();
        private RouteImgDao routeImgDao = new RouteImgDaoImpl();
        private SellerDao sellerDao = new SellerDaoImpl();
        private FavoriteDao favoriteDao = new FavoriteDaoImpl();
    
        @Override
        public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize,String rname) {
            //封装pageBean
            PageBean<Route> pb = new PageBean<>();
            //设置当前页码
            pb.setCurrentPage(currentPage);
            //设置每页显示条数
            pb.setPageSize(pageSize);
    
            //设置总记录数
            int totalCount = routeDao.findTotalCount(cid,rname);
            pb.setTotalCount(totalCount);
    
            //设置当前页显示的数据集合
            int start = (currentPage - 1) * pageSize;//开始的记录数
            List<Route> list = routeDao.findByPage(cid,start,pageSize,rname);
            pb.setList(list);
    
            //设置总页数 = 总记录数/每页显示条数
            int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize :(totalCount / pageSize) + 1 ;
            pb.setTotalPage(totalPage);
    
            return pb;
        }
    
        /*
        根据id查询
         */
        @Override
        public Route findOne(String rid) {
            //1.根据id去route表中查询route对象
            Route route = routeDao.findOne(Integer.parseInt(rid));
            //2.根据route的id查询图片的集合信息
            List<RouteImg> routeImgList = routeImgDao.findByRid(route.getRid());
            //2.1将集合设置到route对象
            route.setRouteImgList(routeImgList);
            //3.根据route的sid(商家id)查询商家对象
            Seller seller = sellerDao.findById(route.getSid());
            route.setSeller(seller);
            //4. 查询收藏次数
            int count = favoriteDao.findCountByRid(route.getRid());
            route.setCount(count);
            return route;
        }
    }

    FavoriteDao

    package cn.itcast.travel.dao;
    
    import cn.itcast.travel.domain.Favorite;
    
    public interface FavoriteDao {
    
        /**
         * 根据rid和uid查询收藏信息
         */
        Favorite findByRidAndUid(int rid, int uid);
    
        /*
            根据rid 查询收藏次数
         */
        int findCountByRid(int rid);
    }
    package cn.itcast.travel.dao.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.domain.Favorite;
    import cn.itcast.travel.util.JDBCUtils;
    import org.springframework.dao.DataAccessException;
    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 Favorite findByRidAndUid(int rid, int uid) {
            Favorite favorite = null;
            try {
                String sql = " select * from tab_favorite where rid = ? and uid = ?";
                favorite = template.queryForObject(sql, new BeanPropertyRowMapper<Favorite>(Favorite.class), rid, uid);
            } catch (DataAccessException e) {
                e.printStackTrace();
            }
            return favorite;
        }
    
        @Override
        public int findCountByRid(int rid) {
            String sql = "SELECT COUNT(*) FROM tab_favorite WHERE rid = ?";
    
            return template.queryForObject(sql,Integer.class,rid);
        }
    
    }

    12.5点击按钮收藏线路

     分析

    前台代码

    <!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">
    
    </head>
    
    <body>
    <!--引入头部-->
    <div id="header"></div>
    <!-- 详情 start -->
    <div class="wrap">
        <div class="bread_box">
            <a href="/">首页</a>
            <span> &gt;</span>
            <a href="#">国内游</a><span> &gt;</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="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>
            </dl>
            <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-9090</span></p>
                    <p>地址 : <span id="address">传智播客黑马程序员</span></p>
                </div>
                <div class="pros_price">
                    <p class="price"><strong id="price">¥2699.00</strong><span></span></p>
                    <p class="collect">
                        <a class="btn" id="favorite" onclick="addFavorite();"><i
                                class="glyphicon glyphicon-heart-empty"></i>点击收藏</a>
    
                        <!--<a class="btn already" disabled="disabled"><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>
    
    <script src="js/getParameter.js"></script>
    
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    <script>
        $(document).ready(function () {
            goImg();
        });
    
        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 () {
            //1.获取id
            var rid = getParameter("rid");
            //2.发送请求请求 route/findOne
            $.get("route/findOne", {rid: rid}, function (route) {
                //3.解析数据填充html
                $("#rname").html(route.rname);
                $("#routeIntroduce").html(route.routeIntroduce);
                $("#price").html("¥" + route.price);
                $("#sname").html(route.seller.sname);
                $("#consphone").html(route.seller.consphone);
                $("#address").html(route.seller.address);
                //设置收藏次数
                $("#favoriteCount").html("已收藏" + route.count + "");
                //图片展示
    
                var ddstr = '<a class="up_img up_img_disable"></a>';
    
                //遍历routeImgList
                for (var i = 0; i < route.routeImgList.length; i++) {
                    var astr;
                    if (i >= 4) {
                        astr = '<a title="" class="little_img" data-bigpic="' + route.routeImgList[i].bigPic + '" style="display:none;">
    ' +
                            '                        <img src="' + route.routeImgList[i].smallPic + '">
    ' +
                            '                    </a>';
                    } else {
                        astr = '<a title="" class="little_img" data-bigpic="' + route.routeImgList[i].bigPic + '">
    ' +
                            '                        <img src="' + route.routeImgList[i].smallPic + '">
    ' +
                            '                    </a>';
                    }
    
                    ddstr += astr;
                }
                ddstr += '<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';
    
                $("#dd").html(ddstr);
    
                //图片展示和切换代码调用
                goImg();
            });
        });
    
        $(function () {
            // 发送请求,判断用户是否收藏过该线路
            var rid = getParameter("rid");
            $.get("route/isFavorite", {rid: rid}, function (flag) {
                if (flag) {
                    // 用户已经收藏过
                    //<a  class="btn already" disabled="disabled">
                    //设置收藏按钮的样式
                    $("#favorite").addClass("already");
                    $("#favorite").attr("disabled", "disabled");
    
                    //删除按钮的点击事件
                    $("#favorite").removeAttr("onclick");
    
                } else {
                    // 用户没有收藏
                }
            });
        });
    
        //点击收藏按钮触发的方法
        function addFavorite(){
            var rid = getParameter("rid");
            //1. 判断用户是否登录
            $.get("user/findOne",{},function (user) {
                if(user){
                    //用户登录了
                    //添加功能
                    $.get("route/addFavorite",{rid:rid},function () {
    
                        //代码刷新页面
                        location.reload();
                    });
    
                }else{
                    //用户没有登录
                    alert("您尚未登录,请登录");
                    location.href="http://localhost/travel/login.html";
                }
            })
        }
    
    </script>
    </body>
    
    </html>

    后台代码

    package cn.itcast.travel.web.servlet;
    
    import cn.itcast.travel.domain.PageBean;
    import cn.itcast.travel.domain.Route;
    import cn.itcast.travel.domain.User;
    import cn.itcast.travel.service.FavoriteService;
    import cn.itcast.travel.service.RouteService;
    import cn.itcast.travel.service.impl.FavoriteServiceImpl;
    import cn.itcast.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 pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.接受参数
            String currentPageStr = request.getParameter("currentPage");
            String pageSizeStr = request.getParameter("pageSize");
            String cidStr = request.getParameter("cid");
            //接受rname路线名称
            String rname = request.getParameter("rname");
            rname = new String(rname.getBytes("iso-8859-1"),"utf-8");
    
            //2.处理参数
            int cid = 0;//类别id
            if(cidStr != null && cidStr.length() > 0 && !"null".equals(cidStr)){
                cid = Integer.parseInt(cidStr);
            }
    
            int currentPage = 0;//当前页码,默认为第一页
            if (currentPageStr != null && currentPageStr.length() > 0) {
                currentPage = Integer.parseInt(currentPageStr);
            } else {
                currentPage = 1;
            }
    
            int pageSize = 0;//每页显示条数,默认显示5条
            if (pageSizeStr != null && pageSizeStr.length() > 0) {
                pageSize = Integer.parseInt(pageSizeStr);
            } else {
                pageSize = 5;
            }
    
            //3. 调用service查询PageBean对象
            PageBean<Route> pb = routeService.pageQuery(cid, currentPage, pageSize,rname);
    
            //4. 将pageBean对象序列化为json,返回
            writeValue(pb, response);
        }
    
        /*
        根据id查询一个旅游线路的详细信息
         */
        public void findOne(HttpServletRequest request,HttpServletResponse response) throws IOException {
            //1.接收id
            String rid = request.getParameter("rid");
            //2.调用service查询route对象
            Route route = routeService.findOne(rid);
            //转为json写入客户端
            writeValue(route,response);
        }
    
        /*
        判断当前用户是否收藏过该线路
         */
        public void isFavorite(HttpServletRequest request,HttpServletResponse response) throws IOException {
            //1.获取线路id
            String rid = request.getParameter("rid");
    
            //2.获取当前登录的用户user
            User user = (User) request.getSession().getAttribute("user");
            int uid;//用户的id
            if(user==null){
                //用户尚未登录
                uid = 0;
            }else {
                //用户已经登录
                uid=user.getUid();
            }
    
            //3. 调用FavoriteService查询是否收藏
            boolean flag = favoriteService.isFavorite(rid, uid);
    
            //4. 写回客户端
            writeValue(flag,response);
    
        }
    
        /**
         * 添加收藏
         * @param request
         * @param response
         * @throws ServletException
         * @throws IOException
         */
        public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1. 获取线路rid
            String rid = request.getParameter("rid");
            //2. 获取当前登录的用户
            User user = (User) request.getSession().getAttribute("user");
            int uid;//用户id
            if(user == null){
                //用户尚未登录
                return ;
            }else{
                //用户已经登录
                uid = user.getUid();
            }
    
    
            //3. 调用service添加
            favoriteService.add(rid,uid);
    
        }
    
    
    }

    FavoriteService

    package cn.itcast.travel.service;
    
    public interface FavoriteService {
    
        /**
         * 判断是否收藏
         */
        boolean isFavorite(String rid, int uid);
    
        void add(String rid, int uid);
    }
    package cn.itcast.travel.service.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.dao.impl.FavoriteDaoImpl;
    import cn.itcast.travel.domain.Favorite;
    import cn.itcast.travel.service.FavoriteService;
    
    public class FavoriteServiceImpl implements FavoriteService {
    
        private FavoriteDao favoriteDao = new FavoriteDaoImpl();
    
        @Override
        public boolean isFavorite(String rid, int uid) {
    
            Favorite favorite = favoriteDao.findByRidAndUid(Integer.parseInt(rid), uid);
    
            return favorite != null;//如果对象有值,则为true,反之,则为false
        }
    
        @Override
        public void add(String rid, int uid) {
            favoriteDao.add(Integer.parseInt(rid),uid);
        }
    }

    FavoriteDao

    package cn.itcast.travel.dao;
    
    import cn.itcast.travel.domain.Favorite;
    
    public interface FavoriteDao {
    
        /**
         * 根据rid和uid查询收藏信息
         */
        Favorite findByRidAndUid(int rid, int uid);
    
        /*
            根据rid 查询收藏次数
         */
        int findCountByRid(int rid);
    
        void add(int rid, int uid);
    }
    package cn.itcast.travel.dao.impl;
    
    import cn.itcast.travel.dao.FavoriteDao;
    import cn.itcast.travel.domain.Favorite;
    import cn.itcast.travel.util.JDBCUtils;
    import org.springframework.dao.DataAccessException;
    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 Favorite findByRidAndUid(int rid, int uid) {
            Favorite favorite = null;
            try {
                String sql = " select * from tab_favorite where rid = ? and uid = ?";
                favorite = template.queryForObject(sql, new BeanPropertyRowMapper<Favorite>(Favorite.class), rid, uid);
            } catch (DataAccessException e) {
    
            }
            return favorite;
        }
    
        @Override
        public int findCountByRid(int rid) {
            String sql = "SELECT COUNT(*) FROM tab_favorite WHERE rid = ?";
    
            return template.queryForObject(sql,Integer.class,rid);
        }
    
        @Override
        public void add(int rid, int uid) {
            String sql = "insert into tab_favorite values(?,?,?)";
    
            template.update(sql,rid,new Date(),uid);
        }
    
    }
  • 相关阅读:
    Android 调用已安装市场,进行软件评分的功能实现
    二十六个月Android学习工作总结
    Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1) 错误 解决方案(android-ndk)
    【Android】神奇的android:clipChildren属性
    Android利用setLayoutParams在代码中调整布局(Margin和居中)
    android 使用代码实现 RelativeLayout布局
    Android 布局学习
    Erlang cowboy 处理不规范的client
    HTTP 响应
    把字符串转换为整数
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/11966416.html
Copyright © 2020-2023  润新知