实战SSM_O2O商铺_43【前端展示】店铺详情页面从后端到前端的实现

简介: 实战SSM_O2O商铺_43【前端展示】店铺详情页面从后端到前端的实现

概述

店铺列表页面完成后,接下来完成点击某个店铺进入店铺详情页面

  • 展示店铺信息
  • 展示商品目录信息
  • 展示商品信息

Dao层

复用之前的代码即可


Service层

复用之前的代码即可


Controller层

package com.artisan.o2o.web.frontend;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.artisan.o2o.dto.ProductExecution;
import com.artisan.o2o.entity.Product;
import com.artisan.o2o.entity.ProductCategory;
import com.artisan.o2o.entity.Shop;
import com.artisan.o2o.service.ProductCategoryService;
import com.artisan.o2o.service.ProductService;
import com.artisan.o2o.service.ShopService;
import com.artisan.o2o.util.HttpServletRequestUtil;
@Controller
@RequestMapping("/frontend")
public class ShopDetailController {
  @Autowired
  private ShopService shopService;
  @Autowired
  private ProductService productService;
  @Autowired
  private ProductCategoryService productCategoryService;
  @RequestMapping(value = "/listshopdetailpageinfo", method = RequestMethod.GET)
  @ResponseBody
  private Map<String, Object> listShopDetailPageInfo(
      HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    long shopId = HttpServletRequestUtil.getLong(request, "shopId");
    Shop shop = null;
    List<ProductCategory> productCategoryList = null;
    if (shopId != -1) {
      shop = shopService.getShopById(shopId);
      productCategoryList = productCategoryService.queryProductCategoryList(shopId);
      modelMap.put("shop", shop);
      modelMap.put("productCategoryList", productCategoryList);
      modelMap.put("success", true);
    } else {
      modelMap.put("success", false);
      modelMap.put("errMsg", "empty shopId");
    }
    return modelMap;
  }
  @RequestMapping(value = "/listproductsbyshop", method = RequestMethod.GET)
  @ResponseBody
  private Map<String, Object> listProductsByShop(HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    int pageIndex = HttpServletRequestUtil.getInt(request, "pageIndex");
    int pageSize = HttpServletRequestUtil.getInt(request, "pageSize");
    long shopId = HttpServletRequestUtil.getLong(request, "shopId");
    if ((pageIndex > -1) && (pageSize > -1) && (shopId > -1)) {
      long productCategoryId = HttpServletRequestUtil.getLong(request,
          "productCategoryId");
      String productName = HttpServletRequestUtil.getString(request,
          "productName");
      Product productCondition = compactProductCondition4Search(shopId,
          productCategoryId, productName);
      ProductExecution pe = productService.queryProductionList(
          productCondition, pageIndex, pageSize);
      modelMap.put("productList", pe.getProductList());
      modelMap.put("count", pe.getCount());
      modelMap.put("success", true);
    } else {
      modelMap.put("success", false);
      modelMap.put("errMsg", "empty pageSize or pageIndex or shopId");
    }
    return modelMap;
  }
  private Product compactProductCondition4Search(long shopId,
      long productCategoryId, String productName) {
    Product productCondition = new Product();
    Shop shop = new Shop();
    shop.setShopId(shopId);
    productCondition.setShop(shop);
    if (productCategoryId != -1L) {
      ProductCategory productCategory = new ProductCategory();
      productCategory.setProductCategoryId(productCategoryId);
      productCondition.setProductCategory(productCategory);
    }
    if (productName != null) {
      productCondition.setProductName(productName);
    }
    productCondition.setEnableStatus(1);
    return productCondition;
  }
}


View层

shopdetail.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>商店详情</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<link rel="shortcut icon" href="/o2o/favicon.ico">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet"
  href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
<link rel="stylesheet"
  href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css">
<link rel="stylesheet"
  href="../resources/css/frontend/shopdetail/shopdetail.css">
</head>
<body>
  <div class="page-group">
    <div class="page">
      <header class="bar bar-nav">
        <a class="button button-link button-nav pull-left" external href="#"
          onClick="javascript :history.back(-1);" data-transition='slide-out'>
          <span class="icon icon-left"></span> 返回
        </a>
        <h1 class="title" id="shop-name">店铺详情</h1>
      </header>
      <nav class="bar bar-tab">
        <a class="tab-item" href="/o2o/frontend/index" external> <span
          class="icon icon-home"></span> <span class="tab-label">首页</span>
        </a> <a class="tab-item" href="#" id="me"> <span
          class="icon icon-me"></span> <span class="tab-label">我</span>
        </a>
      </nav>
      <div class="content infinite-scroll infinite-scroll-bottom"
        data-distance="100">
        <!-- 这里是页面内容区 -->
        <div class="shop-detail-dev">
          <div class="card">
            <div valign="bottom"
              class="card-header color-white no-border no-padding">
              <img class='card-cover' id="shop-cover-pic" src="" alt="">
            </div>
            <div class="card-content">
              <div class="card-content-inner">
                <p class="color-gray">
                  <span id="shop-update-time"></span>
                </p>
                <p id="shop-desc"></p>
              </div>
            </div>
            <div class="card-footer">
              <!-- <a href="#" class="link">赞</a> -->
              <!-- <a href="#" class="link">更多</a> -->
              <span id="shop-addr"></span><span id="shop-phone"></span>
            </div>
          </div>
        </div>
        <div class="shopdetail-button-div" id="shopdetail-button-div">
          <!-- <a href="#" class="button">所有货物</a>
                        <a href="#" class="button">吃的</a>
                        <a href="#" class="button">喝的</a>
                        <a href="#" class="button">Usual Button 1</a>
                        <a href="#" class="button">Usual Button 1</a>
                        <a href="#" class="button">Usual Button 1</a> -->
        </div>
        <div class="detail-search">
          <div class="searchbar">
            <a class="searchbar-cancel">取消</a>
            <div class="search-input">
              <label class="icon icon-search" for="search"></label> <input
                type="search" id='search' placeholder='输入关键字...' />
            </div>
          </div>
        </div>
        <div class="list-div">
          <!-- <div class="card">
                            <div class="card-header">传统火锅店</div>
                            <div class="card-content">
                                <div class="list-block media-list">
                                    <ul>
                                        <li class="item-content">
                                            <div class="item-media">
                                                <img src="http://gqianniu.alicdn.com/bao/uploaded/i4//tfscom/i3/TB10LfcHFXXXXXKXpXXXXXXXXXX_!!0-item_pic.jpg_250x250q60.jpg" width="44">
                                            </div>
                                            <div class="item-inner">
                                                <div class="item-subtitle"></div>
                                            </div>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                            <div class="card-footer">
                                <span>2015/01/15</span>
                                <span>5 评论</span>
                            </div>
                        </div> -->
        </div>
        <div class="infinite-scroll-preloader">
          <div class="preloader"></div>
        </div>
      </div>
    </div>
    <!--侧边栏  -->
    <div class="panel-overlay"></div>
    <div class="panel panel-right panel-reveal" id="panel-left-demo">
      <div class="content-block">
        <p>
          <a href="/o2o/frontend/myrecord" class="close-panel">消费记录</a>
        </p>
        <p>
          <a href="/o2o/frontend/mypoint" class="close-panel">我的积分</a>
        </p>
        <p>
          <a href="/o2o/frontend/pointrecord" class="close-panel">积分兑换记录</a>
        </p>
        <!-- Click on link with "close-panel" class will close panel -->
      </div>
    </div>
  </div>
  <script type='text/javascript'
    src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script>
  <script type='text/javascript'
    src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script>
  <script type='text/javascript'
    src='//g.alicdn.com/msui/sm/0.6.2/js/sm-extend.min.js' charset='utf-8'></script>
  <script type='text/javascript'
    src='../resources/js/common/common.js' charset='utf-8'></script>
  <script type='text/javascript'
    src='../resources/js/frontend/shopdetail.js' charset='utf-8'></script>
</body>
</html>


shopdetail.js

$(function() {
  var loading = false;
  var maxItems = 20;
  var pageSize = 10;
  var listUrl = '/o2o/frontend/listproductsbyshop';
  var pageNum = 1;
  var shopId = getQueryString('shopId');
  var productCategoryId = '';
  var productName = '';
  var searchDivUrl = '/o2o/frontend/listshopdetailpageinfo?shopId=' + shopId;
  getSearchDivData();
  addItems(pageSize, pageNum);
  function getSearchDivData() {
    var url = searchDivUrl;
    $.getJSON(url,
        function(data) {
          if (data.success) {
            var shop = data.shop;
            $('#shop-cover-pic').attr('src', shop.shopImg);
            $('#shop-update-time').html(
                new Date(shop.lastEditTime)
                    .Format("yyyy-MM-dd"));
            $('#shop-name').html(shop.shopName);
            $('#shop-desc').html(shop.shopDesc);
            $('#shop-addr').html(shop.shopAddr);
            $('#shop-phone').html(shop.phone);
            var productCategoryList = data.productCategoryList;
            var html = '';
            productCategoryList
                .map(function(item, index) {
                  html += '<a href="#" class="button" data-product-search-id='
                      + item.productCategoryId
                      + '>'
                      + item.productCategoryName
                      + '</a>';
                });
            $('#shopdetail-button-div').html(html);
          }
        });
  }
  function addItems(pageSize, pageIndex) {
    // 生成新条目的HTML
    var url = listUrl + '?' + 'pageIndex=' + pageIndex + '&pageSize='
        + pageSize + '&productCategoryId=' + productCategoryId
        + '&productName=' + productName + '&shopId=' + shopId;
    loading = true;
    $.getJSON(url, function(data) {
      if (data.success) {
        maxItems = data.count;
        var html = '';
        data.productList.map(function(item, index) {
          html += '' + '<div class="card" data-product-id='
              + item.productId + '>'
              + '<div class="card-header">' + item.productName
              + '</div>' + '<div class="card-content">'
              + '<div class="list-block media-list">' + '<ul>'
              + '<li class="item-content">'
              + '<div class="item-media">' + '<img src="'
              + item.imgAddr + '" width="44">' + '</div>'
              + '<div class="item-inner">'
              + '<div class="item-subtitle">' + item.productDesc
              + '</div>' + '</div>' + '</li>' + '</ul>'
              + '</div>' + '</div>' + '<div class="card-footer">'
              + '<p class="color-gray">'
              + new Date(item.lastEditTime).Format("yyyy-MM-dd")
              + '更新</p>' + '<span>点击查看</span>' + '</div>'
              + '</div>';
        });
        $('.list-div').append(html);
        var total = $('.list-div .card').length;
        if (total >= maxItems) {
          // 隐藏加载提示符
          $('.infinite-scroll-preloader').hide();
        }else{
          $('.infinite-scroll-preloader').show();
        }
        pageNum += 1;
        loading = false;
        $.refreshScroller();
      }
    });
  }
  $(document).on('infinite', '.infinite-scroll-bottom', function() {
    if (loading)
      return;
    addItems(pageSize, pageNum);
  });
  $('#shopdetail-button-div').on(
      'click',
      '.button',
      function(e) {
        productCategoryId = e.target.dataset.productSearchId;
        if (productCategoryId) {
          if ($(e.target).hasClass('button-fill')) {
            $(e.target).removeClass('button-fill');
            productCategoryId = '';
          } else {
            $(e.target).addClass('button-fill').siblings()
                .removeClass('button-fill');
          }
          $('.list-div').empty();
          pageNum = 1;
          addItems(pageSize, pageNum);
        }
      });
  $('.list-div')
      .on('click',
        '.card',
        function(e) {
            var productId = e.currentTarget.dataset.productId;
            window.location.href = '/o2o/frontend/productdetail?productId='
                + productId;
          });
  $('#search').on('change', function(e) {
    productName = e.target.value;
    $('.list-div').empty();
    pageNum = 1;
    addItems(pageSize, pageNum);
  });
  $('#me').click(function() {
    $.openPanel('#panel-left-demo');
  });
  $.init();
});


shopdetail.css

.detail-search {
    height: 2.2rem;
    padding-right: .5rem;
    padding-left: .5rem;
    background-color: #f7f7f8;
}
.infinite-scroll-preloader {
    margin-top: -5px;
}
.shopdetail-button-div {
    margin: 0 .3rem;
}
.shopdetail-button-div > .button {
    width: 30%;
    height: 1.5rem;
    line-height: 1.5rem;
    display: inline-block;
    margin: 1%;
    overflow: hidden;
}


#FrontEndController添加路由

@RequestMapping(value = "/shopdetail", method = RequestMethod.GET)
  public String shopDetail() {
    return "frontend/shopdetail";
  }


商品详情待开发

TODO


Github地址

代码地址: https://github.com/yangshangwei/o2o

目录
打赏
0
0
0
0
99
分享
相关文章
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
142 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
73 14
陪练,代练,护航,代打小程序源码/前端UNIAPP-VUE2.0开发 后端Thinkphp6管理/具备家政服务的综合型平台
这款APP通过技术创新,将代练、家政、娱乐社交等场景融合,打造“全能型生活服务生态圈”。以代练为切入点,提供模块化代码支持快速搭建平台,结合智能匹配与技能审核机制,拓展家政服务和商业管理功能。技术架构具备高安全性和扩展性,支持多业务复用,如押金冻结、录屏监控等功能跨领域应用。商业模式多元,包括交易抽成、增值服务及广告联名,同时设计跨领域积分体系提升用户粘性,实现生态共生与B端赋能。
61 9
前端uin后端php社交软件源码,快速构建属于你的交友平台
这是一款功能全面的社交软件解决方案,覆盖多种场景需求。支持即时通讯(一对一聊天、群聊、文件传输、语音/视频通话)、内容动态(发布、点赞、评论)以及红包模块(接入支付宝、微信等第三方支付)。系统采用前后端分离架构,前端基于 UniApp,后端使用 PHP 框架(如 Laravel/Symfony),配合 MySQL/Redis 和自建 Socket 服务实现高效实时通信。提供用户认证(JWT 集成)、智能匹配算法等功能,助力快速上线,显著节约开发成本。
34 0
前端uin后端php社交软件源码,快速构建属于你的交友平台
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
110 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
构建高效Java后端与前端交互的定时任务调度系统
通过以上步骤,我们构建了一个高效的Java后端与前端交互的定时任务调度系统。该系统使用Spring Boot作为后端框架,Quartz作为任务调度器,并通过前端界面实现用户交互。此系统可以应用于各种需要定时任务调度的业务场景,如数据同步、报告生成和系统监控等。
78 9
【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
本文介绍了如何配置和启动基于Java的若依(RuoYi)项目,涵盖后端和前端的详细步骤。首先,准备Redis、MySQL以及IDE(如Idea和VS)。接着,通过GitHub获取代码并导入到IDE中,执行必要的SQL文件和配置数据库密码。然后,启动Redis并进行相关配置。最后,按照前端配置步骤克隆前端代码库,打开终端执行命令完成前端配置。整个过程详细记录了每一步的操作,帮助开发者顺利部署若依项目。 如果你觉得有帮助,请点赞、关注和收藏,这将是我持续分享的动力!
1264 2
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
367 3
前端状态管理:Vuex 核心概念与实战
Vuex 是 Vue.js 应用程序的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。本教程将深入讲解 Vuex 的核心概念,如 State、Getter、Mutation 和 Action,并通过实战案例帮助开发者掌握在项目中有效使用 Vuex 的技巧。
前端性能优化实战:从加载速度到用户体验
前端性能优化实战:从加载速度到用户体验

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等