美文网首页开发设计
实现商品列表状态及查询

实现商品列表状态及查询

作者: 岳峙 | 来源:发表于2019-03-22 16:46 被阅读42次
image.png

分析requestURL,首先提交的路径是/spu/page/,后面加着四个参数 分别是page(第几页) key (默认是第一页) rows 显示几行(默认是五行数据) key() saleable 上架情况 默认是false 以及key key中主要是带着以上的那些值信息
然后看表的结构
首先需要清除两个关键词就是SKU 和 SPU
SPU = Standard Product Unit (标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
在商品信息电子化过程中,商品的特性可以由多个“属性|属性值对”进行描述。“属性|属性值对”完全相同的商品,可以抽象成为一个SPU。
另一方面,这些“属性|属性值对”在SPU中固化下来,逐步标准化。
基于SPU的商品信息结构,可以实现丰富的应用,比如商品信息与资讯、评论、以及其它SPU的整合。
例如:iPhone X 可以确定一个产品即为一个SPU。

SKU=Stock Keeping Unit(库存量单位)。
针对电商而言:
1、SKU是指一款商品,每款都有出现一个SKU,便于电商品牌识别商品。
2、一款商品多色,则是有多个SKU,例:一件衣服,有红色、白色、蓝色,则SKU编码也不相同,如相同则会出现混淆,发错货。
例如:iPhone X 64G 银色 则是一个SKU。
总的来说就是一件商品对应一个spu
具体的商品的具体的规格颜色型号各对应一个唯一的sku

看下数据库


image.png image.png

可以看到spu是手机的型号 但是sku就更加细了 是spu的子集
创建相应的pojo

package com.leyou.item.pojo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import javax.persistence.*;
import java.util.Date;

@Table(name = "tb_spu")
@Data
public class Spu {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long brandId;
    private Long cid1;// 1级类目
    private Long cid2;// 2级类目
    private Long cid3;// 3级类目
    private String title;// 标题
    private String subTitle;// 子标题
    private Boolean saleable;// 是否上架
    @JsonIgnore
    private Boolean valid;// 是否有效,逻辑删除用
    private Date createTime;// 创建时间
    @JsonIgnore//返回页面时忽略此字段
    private Date lastUpdateTime;// 最后修改时间
    @Transient
    private String cname;
    @Transient
    private String bname;

    // 省略getter和setter
}
package com.leyou.item.pojo;

import lombok.Data;

import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="tb_spu_detail")
@Data
public class SpuDetail {
    @Id
    private Long spuId;// 对应的SPU的id
    private String description;// 商品描述
    private String specTemplate;// 商品特殊规格的名称及可选值模板
    private String specifications;// 商品的全局规格属性
    private String packingList;// 包装清单
    private String afterService;// 售后服务
    // 省略getter和setter
}

创建mapper

package com.leyou.item.mapper;

import com.leyou.item.pojo.Spu;
import tk.mybatis.mapper.common.Mapper;

/**
 * @Author: Pandy
 * @Date: 2019/3/22 12:17
 * @Version 1.0
 */
public interface SpuMapper extends Mapper<Spu> {

}

package com.leyou.item.mapper;

import com.leyou.item.pojo.SpuDetail;
import tk.mybatis.mapper.common.Mapper;

/**
 * @Author: Pandy
 * @Date: 2019/3/22 12:17
 * @Version 1.0
 */
public interface SpuDetailMapper extends Mapper<SpuDetail> {

}

controller

package com.leyou.item.web;

import com.leyou.common.vo.PageResult;
import com.leyou.item.pojo.Spu;
import com.leyou.item.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.xml.ws.Response;

/**
 * @Author: Pandy
 * @Date: 2019/3/22 12:19
 * @Version 1.0
 */
@RestController
public class GoodsController {

    @Autowired
    private GoodsService goodsService;
    /**
     * 分页查询Spu
     * @param page
     * @param rows
     * @param saleable
     * @param key
     * @return
     */
    @GetMapping("/spu/page")
    public ResponseEntity<PageResult<Spu>> querySpuByPage(
            @RequestParam(value = "page",defaultValue = "1") Integer page,
            @RequestParam(value = "rows",defaultValue = "5") Integer rows,
            @RequestParam(value = "saleable",required = false) Boolean saleable,
            @RequestParam(value = "key",required = false) String key
    ){
        return ResponseEntity.ok(goodsService.querySpuByPage(page,rows,saleable,key));
    }
}

注意controller中传递过来的字段
并且我们直接在返回体中调用相应的方法

ResponseEntity :标识整个http相应:状态码、头部信息、响应体内容(spring)

@ResponseBody:加在请求处理方法上,能够处理方法结果值作为http响应体(springmvc)

@ResponseStatus:加在方法上、返回自定义http状态码(spring)

service是最难写 也是最重要的

package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnums;
import com.leyou.common.exception.LyException;
import com.leyou.common.vo.PageResult;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.pojo.Category;
import com.leyou.item.pojo.Spu;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: Pandy
 * @Date: 2019/3/22 12:18
 * @Version 1.0
 */
@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    public PageResult<Spu> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        //分页
        PageHelper.startPage(page,rows);
        //过滤
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //搜索字段过滤
        if (StringUtils.isNotBlank(key)){
            criteria.andLike("title","%"+key+"%");
        }
        //上下架过滤
        if(saleable != null){
            criteria.andEqualTo("saleable",saleable);
        }
        //排序
        example.setOrderByClause("last_update_time DESC");
        //查询
        List<Spu> spus = spuMapper.selectByExample(example);
        //判断
        if (CollectionUtils.isEmpty(spus)){
            throw  new LyException(ExceptionEnums.PRODUCT_NOT_FOUND);
        }
        //解析分类和品牌的名称
        loadCategoryAndBrandName(spus);


        //解析分页的结果
        PageInfo<Spu> info = new PageInfo<>(spus);
        return new PageResult<>(info.getTotal(),spus);
    }

    private void loadCategoryAndBrandName(List<Spu> spus) {
        for (Spu spu:spus){
            //处理分类名称
            List<String> names = categoryService.queryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()))
                    .stream().map(Category::getName).collect(Collectors.toList());
            //reduce((s,s2)->s+s2);也可以进行拼接
            spu.setCname(StringUtils.join(names,"/"));//集合拼成字符串
            //处理品牌名称
            spu.setBname(brandService.queryById(spu.getBrandId()).getName());
        }
    }
}

需要在brandService中加入方法

    public Brand queryById(Long id){
        Brand brand = brandMapper.selectByPrimaryKey(id);
        if (brand == null){
            throw new LyException(ExceptionEnums.BRAND_NOT_FOUND);
        }
        return brand;
    }

在 category中加入查询多个id的方法

    public List<Category> queryByIds(List<Long> ids){
        List<Category> categories = categoryMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(categories)){
            throw new LyException(ExceptionEnums.CATEGORY_NOT_FOUND);
        }
        return categories;
    }

注意上面的mapper文件实现的接口
注意在GoodsController中进行的拼接 使用列表 然后使用String的工具类进行相关的拼接完成

将界面上的所有操作都实现了 我们其实遵循前后端分离的思想向前台传递数据与指令 也就是数据和上面的四个值而已 前台会自动进行处理

最终页面正常显示 功能正常


image.png

相关文章

网友评论

    本文标题:实现商品列表状态及查询

    本文链接:https://www.haomeiwen.com/subject/fmlrvqtx.html