实战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

相关文章
|
10月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
962 1
|
6月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
289 5
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
638 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
11月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
628 70
|
10月前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
550 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
9月前
|
人工智能 监控 前端开发
AI工具:前端与后端的终极对决?谁将成为新时代的宠儿?
深入探讨AI工具对前端和后端开发的具体影响、各自的机遇与挑战,并分析未来开发者如何驾驭AI,实现能力跃迁。
556 0
|
12月前
|
前端开发 算法 NoSQL
前端uin后端php社交软件源码,快速构建属于你的交友平台
这是一款功能全面的社交软件解决方案,覆盖多种场景需求。支持即时通讯(一对一聊天、群聊、文件传输、语音/视频通话)、内容动态(发布、点赞、评论)以及红包模块(接入支付宝、微信等第三方支付)。系统采用前后端分离架构,前端基于 UniApp,后端使用 PHP 框架(如 Laravel/Symfony),配合 MySQL/Redis 和自建 Socket 服务实现高效实时通信。提供用户认证(JWT 集成)、智能匹配算法等功能,助力快速上线,显著节约开发成本。
430 2
前端uin后端php社交软件源码,快速构建属于你的交友平台
|
监控 前端开发 Java
构建高效Java后端与前端交互的定时任务调度系统
通过以上步骤,我们构建了一个高效的Java后端与前端交互的定时任务调度系统。该系统使用Spring Boot作为后端框架,Quartz作为任务调度器,并通过前端界面实现用户交互。此系统可以应用于各种需要定时任务调度的业务场景,如数据同步、报告生成和系统监控等。
650 9
|
前端开发 NoSQL Java
【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
本文介绍了如何配置和启动基于Java的若依(RuoYi)项目,涵盖后端和前端的详细步骤。首先,准备Redis、MySQL以及IDE(如Idea和VS)。接着,通过GitHub获取代码并导入到IDE中,执行必要的SQL文件和配置数据库密码。然后,启动Redis并进行相关配置。最后,按照前端配置步骤克隆前端代码库,打开终端执行命令完成前端配置。整个过程详细记录了每一步的操作,帮助开发者顺利部署若依项目。 如果你觉得有帮助,请点赞、关注和收藏,这将是我持续分享的动力!
7433 4
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
1087 4

热门文章

最新文章