电商门户网站商品品类多级联动springboot+thymeleaf实现

SmileNicky的博客      2022-04-17     350

关键词:

在淘宝、京东等电商网站,其门户网站都有一个商品品类的多级联动,鼠标移动,就显示,因为前端不是我做的,所以不说明前端实现,只介绍后端实现。

搭建部署SpringBoot环境
配置文件配置:
开启了对Thymeleaf模块引擎的支持

server:
  port: 8081
#logging:
#  config: classpath:logback_spring.xml
#  level:
#    com.muses.taoshop: debug
#  path: /data/logs

spring:
  datasource:

    # 主数据源
    shop:
      url: jdbc:mysql://127.0.0.1:3306/taoshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
      username: root
      password: root

    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    # 连接池设置
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      # Oracle请使用select 1 from dual
      validation-query: SELECT ‘x‘
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall‘用于防火墙
      filters: stat,wall,slf4j
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 合并多个DruidDataSource的监控数据
      use-global-data-source-stat: true

#  jpa:
#    database: mysql
#    hibernate:
#      show_sql: true
#      format_sql: true
#      ddl-auto: none
#      naming:
#        physical-strategy: org.hibernate.boot.entity.naming.PhysicalNamingStrategyStandardImpl

#  mvc:
#    view:
#      prefix: /WEB-INF/jsp/
#      suffix: .jsp

  #添加Thymeleaf配置
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML5
    encoding: UTF-8
    content-type: text/html

  #Jedis配置
#  jedis :
#    pool :
#      host : 127.0.0.1
#      port : 6379
#      password : redispassword
#      timeout : 0
#      config :
#        maxTotal : 100
#        maxIdle : 10
#        maxWaitMillis : 100000

SpringBoot启动类:

package com.muses.taoshop;



import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.*;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.bind.annotation.*;
/**
 *
 * <pre>
 *  SpringBoot启动配置类
 * </pre>
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期:     修改内容:
 * </pre>
 */
@Controller
@EnableScheduling//开启对计划任务的支持
@EnableTransactionManagement//开启对事务管理配置的支持
@EnableCaching
@EnableAsync//开启对异步方法的支持
@EnableAutoConfiguration
@ServletComponentScan
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,
        MybatisAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class})
public class PortalApplication {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "portal web!";
    }

    @RequestMapping("/doTest")
    @ResponseBody
    String doTest(){
        System.out.println(Thread.currentThread().getName());
        String threadName = Thread.currentThread().getName();
        return threadName;
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(PortalApplication.class, args);
    }
}

写个Controller类跳转到门户网站:
ps:品类多级联动思路其实就是先构建一个树,我这里的做法就是先查询处理,然后通过工具类,进行递归遍历,待会给出工具类代码,仅供参考。listCategory方法其实就是获取所有的品类信息

package com.muses.taoshop.web.controller.portal;

import com.alibaba.fastjson.JSON;
import com.muses.taoshop.item.entity.ItemBrand;
import com.muses.taoshop.item.entity.ItemCategory;
import com.muses.taoshop.item.entity.ItemPortal;
import com.muses.taoshop.item.service.IItemBrankService;
import com.muses.taoshop.item.service.IItemCategoryService;
import com.muses.taoshop.item.service.IItemService;
import com.muses.taoshop.util.CategoryTreeUtils;
import com.muses.taoshop.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.List;

/**
 * <pre>
 *  门户网站控制类
 * </pre>
 *
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期:     修改内容:
 * </pre>
 */
@Controller
@RequestMapping("/portal")
public class IndexController extends BaseController{

    @Autowired
    IItemService iItemService;
    @Autowired
    IItemBrankService iItemBrankService;
    @Autowired
    IItemCategoryService iItemCategoryService;

    /**
     * 跳转到门户网站
     * @return
     */
    @GetMapping(value = "/toIndex.do")
    public ModelAndView toIndex(){
        info("跳转到门户网站");
        ModelAndView mv = this.getModelAndView();
        mv.setViewName("index");
        List<ItemPortal> items = iItemService.listItemPortal();
        CategoryTreeUtils treeUtil = new CategoryTreeUtils();
        List<ItemCategory> list = iItemCategoryService.listCategory();
        List<ItemCategory> categories = treeUtil.buildCategoryTree(list);
        mv.addObject("items" , items);
        mv.addObject("categories" , categories);
        return mv;
    }

    @GetMapping(value = "/doTest")
    @ResponseBody
    public  String doTest(){
        List<ItemBrand> itemBrands = iItemBrankService.listItemBrand();
        String str = JSON.toJSON(itemBrands).toString();
        return str;
    }


}

业务接口类:

 package com.muses.taoshop.item.service;

import com.muses.taoshop.item.entity.ItemCategory;
import com.muses.taoshop.item.entity.ItemList;

import java.util.List;

/**
 * <pre>
 *  商品品类信息接口
 * </pre>
 *
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2018.06.17 10:59    修改内容:
 * </pre>
 */
public interface IItemCategoryService {
  
    /**
     * 查询所有商品品类信息
     * @return
     */
    List<ItemCategory> listCategory();

    

业务服务实现类:

  package com.muses.taoshop.item.service;

import com.muses.taoshop.item.entity.ItemCategory;
import com.muses.taoshop.item.entity.ItemList;
import com.muses.taoshop.item.mapper.ItemCategoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <pre>
 *  商品品类信息服务实现类
 * </pre>
 *
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2018.06.17 11:01    修改内容:
 * </pre>
 */
@Service
public class ItemCategoryServiceImpl implements IItemCategoryService{

    @Autowired
    ItemCategoryMapper itemCategoryMapper;


    /**
     * 查询所有的商品品类信息
     * @return
     */
    @Override
    public List<ItemCategory> listCategory() {
        return itemCategoryMapper.listCategory();
    }

 


}

Mybatis相关代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.muses.taoshop.item.mapper.ItemCategoryMapper" >
  <resultMap id="BaseResultMap" type="com.muses.taoshop.item.entity.ItemCategory" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="category_name" property="categoryName" jdbcType="VARCHAR" />
    <result column="sjid" property="sjid" jdbcType="BIGINT" />
    <result column="last_modify_time" property="lastModifyTime" jdbcType="TIMESTAMP" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
  </resultMap>

  <sql id="BaseColumnList" >
    id,
        category_name as categoryName,
        sjid,
        last_modify_time as lastModifyTime,
        create_time as createTime
  </sql>
  
    <!-- 获取所有的商品品类信息-->
    <select id="listCategory" resultType="ItemCategory">
        SELECT 
        <include refid="BaseColumnList" />
        FROM item_category t
    </select>
    
</mapper>

Mapper接口类:

package com.muses.taoshop.item.mapper;

import com.muses.taoshop.item.entity.ItemCategory;
import com.muses.taoshop.item.entity.ItemList;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
@Mapper
public interface ItemCategoryMapper {

    List<ItemCategory> listCategory();

   
}

实体类:
这里用了lombok的jar来实现,所有不用set和get方法

package com.muses.taoshop.item.entity;


import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;

/**
 * <pre>
 *  商品品类
 * </pre>
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2018.06.09 21:49    修改内容:
 * </pre>
 */
@Data
public class ItemCategory {
    /**
     * 商品品类id
     */
    private Long id;

    /**
     * 商品品类名称
     */
    private String categoryName;

    /**
     * 上级id
     */
    private Long sjid;

    /**
     * 上次修改时间
     */
    @JSONField(format ="yyyy-MM-dd HH:mm:ss")
    private Date lastModifyTime;

    /**
     * 创建时间
     */
    @JSONField(format ="yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 子菜单
     */
    private List<ItemCategory> subCategorys;


}

构建品类树的工具类:

package com.muses.taoshop.util;

import com.muses.taoshop.item.entity.ItemCategory;

import javax.mail.FetchProfile;
import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 *  构造一棵品类树
 * </pre>
 *
 * @author nicky
 * @version 1.00.00
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2018.06.24 17:12    修改内容:
 * </pre>
 */
public class CategoryTreeUtils {


    public List<ItemCategory> commonCategorys;

    public List<ItemCategory> list = new ArrayList<ItemCategory>();

    public List<ItemCategory> buildCategoryTree(List<ItemCategory> categories ) {
        this.commonCategorys = categories;
        for (ItemCategory c : categories){
            ItemCategory category = new ItemCategory();
            if(c.getSjid() == 0){
                category.setSjid(c.getSjid());
                category.setId(c.getId());
                category.setCategoryName(c.getCategoryName());
                category.setSubCategorys(treeChild(c.getId()));
                list.add(category);
            }
        }
        return list;
    }

    public List<ItemCategory> treeChild(long id){
        List<ItemCategory> list = new ArrayList<ItemCategory>();
        for(ItemCategory c : commonCategorys){
            ItemCategory category = new ItemCategory();
            if(c.getSjid() == id){
                category.setSjid(c.getSjid());
                category.setId(c.getId());
                category.setCategoryName(c.getCategoryName());
                category.setSubCategorys(treeChild(c.getId()));//递归循环
                list.add(category);
            }
        }
        return list;
    }
}

前端代码:

<div class="headerNav" xmlns:th="http://www.thymeleaf.org">
    <div class="layout">
        <dl class="all-brands">
            <dt class="all-brands-head"> <a href="#">全部商品分类</a> </dt>
            <dd class="all-brands-list">
                <div class="wrap" th:each="c : ${categories}">
                    <div class="all-sort-list">
                        <div class="item bo">
                            <h3>
                                <a href="" th:text="${c.categoryName}"></a></h3>
                            <div class="item-list clearfix">
                                <div class="close">x</div>
                                <div class="subitem" th:each="s: ${c.subCategorys}">
                                    <dl class="fore1">
                                        <dt th:text="${s.categoryName}"><a th:href="@{‘/portal/category/toCategoryList/‘+${s.id}}"></a></dt>
                                        <dd>
                                            <em th:each="ss : ${s.subCategorys} "><a th:href="@{‘/portal/category/toCategoryList/‘+${ss.id}}" th:text="${ss.categoryName}"></a></em>
                                        </dd>
                                    </dl>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </dd>
            
        </dl>
      
        </div>
    </div>
</div>

实现的效果如图:可以说是3级联动
技术分享图片

这是在开发中的开源项目的一个小功能,源码已经开源,github链接






创建电商网站

第七章创建电商网站在上一章里,创建了用户关注系统和行为流应用,还学习了使用Django的信号功能与使用Redis数据库存储图片浏览次数和排名。这一章将学习如何创建一个基础的电商网站。本章将学习创建商品品类目录... 查看详情

电商平台应该分析哪些数据?

要想实现精细化运营,数据是必不可少的一个环节。电商网站要提高运营效率,至少需要五大关键指标:活跃用户量、转化率、留存、复购和GMV。活跃用户量是一个基本的指标,有DAU(日活跃用户)、WAU(周活跃用户)和MAU(月... 查看详情

前端静态页面html生活食品电商网站.rar(源码下载-)毕业设计项目

网站静态源码下载,生活食品类电商网站包括商品首页、商品列表、商品详细页、购物车、结账、登录、注册等相关功能.部分网站截图如下:源码下载地址:请点击链接》》》》 查看详情

电商网站的商品详情页系统架构

电商网站的商品详情页系统架构小型电商网站的商品详情页系统架构小型电商网站的页面展示采用页面全量静态化的思想。数据库中存放了所有的商品信息,页面静态化系统,将数据填充进静态模板中,形成静态化页面,推入Ngi... 查看详情

springboot构建电商秒杀项目

...始后,点击进入下单确认页面,并支付成功 二、基于SpringBoot进行项目环境搭建步骤1:创建一个maven工程,使用quickStart骨架。步骤2:在pom.xml导入SpringBoot相关依赖。1<?x 查看详情

springboot构建电商秒杀项目

...始后,点击进入下单确认页面,并支付成功 二、基于SpringBoot进行项目环境搭建步骤1:创建一个maven工程,使用quickStart骨架。步骤2:在pom.xml导入SpringBoot相关依赖。1<?x 查看详情

基于springboot的电商购物平台设计与实现.docx

...调研分析需求以及设计开发本系统的技术要求,采用SpringBoot框架开发Web购物平台应用系统。实现让消费者浏览商品、查看商品详情 查看详情

数据库树形结构多级联动的表设计

...形结构的数据,如何设计表格。场景:省市县三级联动、商品的分类等。参考:https://www.zhihu.com/question/20417447  最常用的一种方法是:将多级数据都放在同一张表中,每条记录用一个parent_id字段存放它对应的父节点的Id,如下... 查看详情

通过s2b2c供应链电商平台网站解决方案,实现大宗商品万亿产业数字化转型

大宗商品作为存量产业规模巨大,全球500种主要工业品,中国有220种工业品的产量全球第一,其余的280种,产能也基本在前五名的水平,以钢材供应链为例,国内钢材供应链市场空间约为2.5万亿元,而... 查看详情

电商网站商品管理

1、document数据格式        面向文档的搜索分析引擎        (1)应用系统的数据结构都是面向对象的        (2)对象数据存储到数据 查看详情

电商网站商品模型之商品详情页设计方案

如下设计方案参考淘宝和华为商城SKUSPU的关系SPU=StandardProductUnit(标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。例如iphone4就是一个SPU,与套餐、存储... 查看详情

电商网站商品模型之商品详情页设计方案

如下设计方案参考淘宝和华为商城SKUSPU的关系SPU=StandardProductUnit(标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。例如iphone4就是一个SPU,与套餐、存储... 查看详情

电商网站中添加商品到购物车功能模块2017.12.8

前言:电商网站中添加商品到购物车功能模块实现:根据前一篇博客的介绍,我们看到淘宝网站为了保证购物车数据的同步,直接是强制用户必须登录才可以将商品加入购物车。而京东网站是用户在未登录的状态下也可以将商品... 查看详情

电商平台应该分析哪些数据?具体怎么去分析

电商平台应该分析的数据和分析的规则如下:1、网站运营指标:网站运营指标主要用来衡量网站的整体运营状况,这里Ec数据分析联盟暂将网站运营指标下面细分为网站流量指标、商品类目指标、以及供应链指标。网站流量指标... 查看详情

电商商品库的产品设计

...规格等信息让我们感觉比在超市拿着实物获得更多信息,电商系统到底是怎么做到这些的呢?对于电商产品经理来说,商品中心的合理设计能够满足前端商品的多样化展示,支撑订单商品信息在系统中的流转。简单粗暴的讲,商... 查看详情

基于springboot电商生鲜购物商城平台设计与实现(含源码+数据库文件)

主要功能:商品分类、商品详情、购物车、订单、用户管理、登录注册、个人中心等功能idea开发工具打开,导入数据库可直接运行登陆注册账号个人中心信息修改更新(个性签名)浏览查看商品信息详情添加商品... 查看详情

如何一步一步用ddd设计一个电商网站——把商品卖给用户

阅读目录前言怎么卖领域服务的使用回到现实结语一、前言  上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计。现在把剩余的“卖”这个动作给做了。这里提醒一下,正常情况下,我们的每一步... 查看详情

分析服务助力产品运营

...;除了基本的用户行为分析如新增、活跃情况等之外,电商APP最重要的就是需要关注用户的付费购买情况,包括商品的销售额、购买品类情况等。因此,一个完整的电商行业分析报告是不可或缺的。华为分析服 查看详情