商城-商品发布(代码生成器的使用)

SPU与SKU概念

SPU = Standard Product Unit  (标准产品单位)

  • 概念 : SPU 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。

  • 通俗点讲,属性值、特性相同的货品就可以称为一个 SPU

==同款商品的公共属性抽取==

例如:**华为P30 就是一个 SPU**

SKU=stock keeping unit( 库存量单位)

  • SKU 即库存进出计量的单位, 可以是以件、盒、托盘等为单位。

  • SKU 是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。

  • 在服装、鞋类商品中使用最多最普遍。

例如:**华为P30 红色 64G 就是一个 SKU**

==某个库存单位的商品独有属性(某个商品的独有属性)==

举例:

优点:更节省空间

表结构分析

tb_spu 表 (SPU表)

字段名称字段含义字段类型字段长度备注
id主键BIGINT  
sn货号VARCHAR  
nameSPU名VARCHAR  
caption副标题VARCHAR  
brand_id品牌IDINT  
category1_id一级分类INT  
category2_id二级分类INT  
category3_id三级分类INT  
template_id模板IDINT  
freight_id运费模板idINT  
image图片VARCHAR  
images图片列表VARCHAR  
sale_service售后服务VARCHAR  
introduction介绍TEXT  
spec_items规格列表VARCHAR  
para_items参数列表VARCHAR  
sale_num销量INT  
comment_num评论数INT  
is_marketable是否上架CHAR  
is_enable_spec是否启用规格CHAR  
is_delete是否删除CHAR  
status审核状态CHAR  

tb_sku 表(SKU商品表)

字段名称字段含义字段类型字段长度备注
id商品idBIGINT  
sn商品条码VARCHAR  
nameSKU名称VARCHAR  
price价格(分)INT  
num库存数量INT  
alert_num库存预警数量INT  
image商品图片VARCHAR  
images商品图片列表VARCHAR  
weight重量(克)INT  
create_time创建时间DATETIME  
update_time更新时间DATETIME  
spu_idSPUIDBIGINT  
category_id类目IDINT  
category_name类目名称VARCHAR  
brand_name品牌名称VARCHAR  
spec规格VARCHAR  
sale_num销量INT  
comment_num评论数INT  
status商品状态 1-正常,2-下架,3-删除CHAR  

商品添加-分类查询实现流程分析

品牌查询实现方案分析

商品添加-规格查询分析

商品添加-参数查询实现

代码生成器使用

将代码生成器code-template拷贝进去:

打开idea,即可看到

添加到maven仓库:

可以看到:

修改代码生成器的配置:

右键Run运行即可:

我反复测试了下,视频自带的资料,和我在网上找的源码中的的代码生成器都不行

还是在官方提供的地址下吧:https://github.com/shenkunlin/code-template.git

下载好解压,操作和上面一样:

测试可以生成,哈哈,测试了好久,终于成功了,有点小成就感。

红叉说明没有jar包,不用担心,直接拷贝过去就好了

只要包的路径一致就ok啦:

package com.changgou.goods

一会儿会用到ID生成,我们可以使用IdWorker,在启动类GoodsApplication中添加如下代码,用于创建IdWorker,并将IdWorker交给Spring容器,代码如下:

/***
 * IdWorker
 * @return
 */
@Bean
public IdWorker idWorker(){
    return new IdWorker(0,0);
}

 工具类在common中:

查询分类:

在实现商品增加之前,需要先选择对应的分类,选择分类的时候,首选选择一级分类,然后根据选中的分类,将选中的分类作为查询的父ID,

再查询对应的子分类集合,因此我们可以在后台编写一个方法,根据父类ID查询对应的分类集合即可。

修改com.changgou.goods.service.CategoryService添加根据父类ID查询所有子节点,代码如下:

/***
 * 根据分类的父ID查询子分类节点集合
 */
List<Category> findByParentId(Integer pid);

修改com.changgou.goods.service.impl.CategoryServiceImpl添加上面的实现,代码如下:

/***
 * 根据分类的父节点ID查询所有子节点
 * @param pid
 * @return
 */
@Override
public List<Category> findByParentId(Integer pid) {
    //SELECT * FROM tb_category WHERE parent_id=?
    Category category = new Category();
    category.setParentId(pid);
    return categoryMapper.select(category);
}

修改com.changgou.goods.controller.CategoryController添加根据父ID查询所有子类集合,代码如下:

/****
 * 根据节点ID查询所有子节点分类集合
 */
@GetMapping(value = "/list/{pid}")
public Result<List<Category>> findByParentId(@PathVariable(value = "pid")Integer pid){
    //调用Service实现查询
    List<Category> categories = categoryService.findByParentId(pid);
    return new Result<List<Category>>(true,StatusCode.OK,"查询成功!",categories);
}

模板查询(规格参数组):

/***
 * 根据分类查询模板数据
 * @param id:分类ID
 */
@GetMapping(value = "/category/{id}")
public Result<Template> findByCategoryId(@PathVariable(value = "id")Integer id){
    //调用Service查询
    Template template = templateService.findByCategoryId(id);
    return new Result<Template>(true, StatusCode.OK,"查询成功",template);
}


/**
 * 根据分类ID查询模板信息
 * @param id
 * @return
 */
Template findByCategoryId(Integer id);


@Autowired
private CategoryMapper categoryMapper;

/***
 * 根据分类ID查询模板信息
 * @param id
 * @return
 */
@Override
public Template findByCategoryId(Integer id) {
    //查询分类信息
    Category category = categoryMapper.selectByPrimaryKey(id);

    //根据模板Id查询模板信息
    return templateMapper.selectByPrimaryKey(category.getTemplateId());
}

查询分类品牌数据:

用户每次选择了分类之后,可以根据用户选择的分类到tb_category_brand表中查询指定的品牌集合ID,

然后根据品牌集合ID查询对应的品牌集合数据,再将品牌集合数据拿到这里来展示即可实现上述功能。

/***
 * 根据分类实现品牌列表查询
 * /brand/category/{id}  分类ID
 */
@GetMapping(value = "/category/{id}")
public Result<List<Brand>> findBrandByCategory(@PathVariable(value = "id")Integer categoryId){
    //调用Service查询品牌数据
    List<Brand> categoryList = brandService.findByCategory(categoryId);
    return new Result<List<Brand>>(true,StatusCode.OK,"查询成功!",categoryList);
}


/***
 * 根据分类ID查询品牌集合
 * @param categoryid:分类ID
 */
List<Brand> findByCategory(Integer categoryid);


/***
 * 根据分类ID查询品牌集合
 * @param categoryid:分类ID
 * @return
 */
@Override
public List<Brand> findByCategory(Integer categoryid) {
    //1.查询当前分类所对应的所有品牌信息
    //2.根据品牌ID查询对应的品牌集合

    //自己创建DAO实现查询
    return brandMapper.findByCategory(categoryid);
}


/***
 * 查询分类对应的品牌集合
 */
@Select("SELECT tb.* FROM tb_category_brand tcb,tb_brand tb WHERE tcb.category_id=#{categoryid} AND tb.id=tcb.brand_id")
List<Brand> findByCategory(Integer categoryid);

规格查询:

/***
 * 根据分类ID查询对应的规格列表
 */
@GetMapping(value = "/category/{id}")
public Result<List<Spec>> findByCategoryId(@PathVariable(value = "id")Integer categoryid){
    //调用Service查询
    List<Spec> specs = specService.findByCategoryId(categoryid);
    return new Result<List<Spec>>(true, StatusCode.OK,"查询成功",specs);
}


/***
 * 根据分类ID查询规格列表
 * @param categoryid
 * @return
 */
List<Spec> findByCategoryId(Integer categoryid);


@Autowired
private CategoryMapper categoryMapper;

/***
 * 根据分类ID查询规格列表
 * @param categoryid
 * @return
 */
@Override
public List<Spec> findByCategoryId(Integer categoryid) {
    //查询分类
    Category category = categoryMapper.selectByPrimaryKey(categoryid);
    //根据分类的模板ID查询规格
    Spec spec = new Spec();
    spec.setTemplateId(category.getTemplateId());
    return specMapper.select(spec);
}

参数列表查询:

/**
 * 根据分类ID查询参数列表
 * @param id
 * @return
 */
@GetMapping(value = "/category/{id}")
public Result<List<Para>> getByCategoryId(@PathVariable(value = "id")Integer id){
    //根据分类ID查询对应的参数信息
    List<Para> paras = paraService.findByCategoryId(id);
    Result<List<Para>> result = new Result<List<Para>>(true,StatusCode.OK,"查询分类对应的品牌成功!",paras);
    return result;
}


/***
 * 根据分类ID查询参数列表
 * @param id
 * @return
 */
List<Para> findByCategoryId(Integer id);


@Autowired
private CategoryMapper categoryMapper;

/***
 * 根据分类ID查询参数列表
 * @param id
 * @return
 */
@Override
public List<Para> findByCategoryId(Integer id) {
    //查询分类信息
    Category category = categoryMapper.selectByPrimaryKey(id);
    //根据分类的模板ID查询参数列表
    Para para = new Para();
    para.setTemplateId(category.getTemplateId());
    return paraMapper.select(para);
}

测试上面的接口:

注册中心:http://localhost:7001/

http://localhost:18081/category/list/0

{
	"flag": true,
	"code": 20000,
	"message": "查询成功!",
	"data": [{
		"id": 1,
		"name": "图书、音像、电子书刊",
		"goodsNum": 100,
		"isShow": "0",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 74,
		"name": "家用电器",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 161,
		"name": "电脑、办公",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 249,
		"name": "个护化妆",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 290,
		"name": "钟表",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 296,
		"name": "母婴",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 378,
		"name": "食品饮料、保健食品",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 438,
		"name": "汽车用品",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 495,
		"name": "玩具乐器",
		"goodsNum": 100,
		"isShow": "0",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 558,
		"name": "手机",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 580,
		"name": "数码",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 43
	},
	{
		"id": 633,
		"name": "家居家装",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 699,
		"name": "厨具",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 749,
		"name": "服饰内衣",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 865,
		"name": "鞋靴",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 903,
		"name": "礼品箱包",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 963,
		"name": "珠宝",
		"goodsNum": 100,
		"isShow": "0",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 1031,
		"name": "运动健康",
		"goodsNum": 100,
		"isShow": "1",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	},
	{
		"id": 1147,
		"name": "彩票、旅行、充值、票务",
		"goodsNum": 100,
		"isShow": "0",
		"isMenu": "0",
		"seq": 1,
		"parentId": 0,
		"templateId": 42
	}]
}

http://localhost:18081/brand/category/11156

{
	"flag": true,
	"code": 20000,
	"message": "查询成功!",
	"data": [{
		"id": 18374,
		"name": "小米",
		"image": "http://img10.360buyimg.com/popshop/jfs/t7084/169/439244907/4647/724c7958/598042c9N6e4e79e5.jpg",
		"letter": "X",
		"seq": null
	},
	{
		"id": 325414,
		"name": "手机配件",
		"image": "",
		"letter": "S",
		"seq": null
	}]
}

 http://localhost:18081/spec/category/11156

{
	"flag": true,
	"code": 20000,
	"message": "查询成功",
	"data": [{
		"id": 27,
		"name": "网络",
		"options": "联通2G,联通3G,联通4G,移动4G,联通3G/移动4G,电信4G",
		"seq": null,
		"templateId": 42
	},
	{
		"id": 28,
		"name": "手机屏幕尺寸",
		"options": "5寸,5.5寸",
		"seq": null,
		"templateId": 42
	},
	{
		"id": 32,
		"name": "机身内存",
		"options": "16G,32G,128G",
		"seq": null,
		"templateId": 42
	},
	{
		"id": 34,
		"name": "存储",
		"options": "16G,32G,64G",
		"seq": null,
		"templateId": 42
	},
	{
		"id": 36,
		"name": "像素",
		"options": "300万像素,800万像素",
		"seq": 1,
		"templateId": 42
	},
	{
		"id": 38,
		"name": "颜色",
		"options": "红,绿,蓝,紫,白,黑",
		"seq": 11,
		"templateId": 42
	},
	{
		"id": 39,
		"name": "测试",
		"options": "实施,学习,实施,测试,显示,s11",
		"seq": 1,
		"templateId": 42
	}]
}

http://localhost:18081/para/category/11156

{
	"flag": true,
	"code": 20000,
	"message": "查询分类对应的品牌成功!",
	"data": [{
		"id": 1,
		"name": "出厂年份",
		"options": "2001,2002,2004,2005",
		"seq": 1,
		"templateId": 42
	},
	{
		"id": 2,
		"name": "版本",
		"options": "10,20,30",
		"seq": 11,
		"templateId": 42
	}]
}

上面接口测试都正确,OK

----------------------------------------------------------------------------------------------------------------------------------------------------------

SPU+SKU保存

保存商品数据的时候,需要保存Spu和Sku,一个Spu对应多个Sku,我们可以先构建一个Goods对象,

SpuList<Sku>组合到一起,前端将2者数据提交过来,再实现添加操作。

Pojo改造

修改changgou-service-goods-api工程创建组合实体类,创建com.changgou.goods.pojo.Goods,代码如下:

package com.changgou.goods.pojo;

import java.io.Serializable;
import java.util.List;

public class Goods implements Serializable {
    //SPU
    private Spu spu;
    //SKU集合
    private List<Sku> skuList;

    public Spu getSpu() {
        return spu;
    }

    public void setSpu(Spu spu) {
        this.spu = spu;
    }

    public List<Sku> getSkuList() {
        return skuList;
    }

    public void setSkuList(List<Sku> skuList) {
        this.skuList = skuList;
    }
}

修改com.changgou.goods.service.SpuService接口,添加保存Goods方法,代码如下:

/**
 * 保存商品
 * @param goods
 */
void saveGoods(Goods goods);

修改com.changgou.goods.service.impl.SpuServiceImpl类,添加保存Goods的方法实现,代码如下:

@Autowired
private IdWorker idWorker;

@Autowired
private CategoryMapper categoryMapper;

@Autowired
private BrandMapper brandMapper;

@Autowired
private SkuMapper skuMapper;

/**
 * 添加商品信息
 * @param goods
 */
@Override
public void saveGoods(Goods goods) {
    //增加Spu
    Spu spu = goods.getSpu();
    spu.setId(idWorker.nextId());//其他属性不填,数据库有默认值,这里可以省略
    spuMapper.insertSelective(spu);

    //增加Sku
    Date date = new Date();
    Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id());
    Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
    //获取Sku集合
    List<Sku> skus = goods.getSkuList();
    //循环将数据加入到数据库
    for (Sku sku : skus) {
        //防止空指针
        if(StringUtils.isEmpty(sku.getSpec())){
            sku.setSpec("{}");
        }
        //构建SKU名称,采用SPU+规格值组装
        //获取Spu的名字
        String name = spu.getName();
        //将规格转换成Map
        Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class);
        //循环组装Sku的名字
        for (Map.Entry<String, String> entry : specMap.entrySet()) {
            name+="  "+entry.getValue();
        }
        sku.setName(name);
        //ID
        sku.setId(idWorker.nextId());
        //SpuId
        sku.setSpuId(spu.getId());
        //创建日期
        sku.setCreateTime(date);
        //修改日期
        sku.setUpdateTime(date);
        //商品分类ID
        sku.setCategoryId(spu.getCategory3Id());
        //分类名字
        sku.setCategoryName(category.getName());
        //品牌名字
        sku.setBrandName(brand.getName());
        //增加
        skuMapper.insertSelective(sku);
    }
}

修改com.changgou.goods.controller.SpuController,增加保存Goods方法,代码如下:

/***
 * 添加Goods
 * @param goods
 * @return
 */
@PostMapping("/save")
public Result save(@RequestBody Goods goods){
    spuService.saveGoods(goods);
    return new Result(true,StatusCode.OK,"保存成功");
}

测试:启动EurekaApplication,启动GoodsApplication

目前前端页面没整合,暂时用测试数据测试

{
  "skuList": [
    {
      "alertNum": 10,
      "brandName": "华为AAA",
      "categoryId": 64,
      "commentNum": 0,
      "image": "http://www.baidu.com",
      "images": "",
      "name": "华为P30手机",
      "num": 5,
      "price": 1000,
      "saleNum": 0,
      "sn": "No1001",
      "spec": "{\"颜色\":\"红色\",\"网络\":\"移动3G\"}",
      "weight": 0
    }
  ],
  "spu": {
    "brandId": 8557,
    "caption": "华为手机大促销",
    "category1Id": 1,
    "category2Id": 59,
    "category3Id": 64,
    "commentNum": 0,
    "freightId": 0,
    "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg",
    "introduction": "华为产品世界最强",
    "isEnableSpec": "1",
    "isMarketable": "1",
    "name": "华为高档手机",
    "specItems": "{\"颜色\":[\"红\",\"绿\"],\"机身内存\":[\"64G\",\"8G\"]}",
    "paraItems": "{\"赠品\":\"充电器\",\"出厂年份\":\"2019\"}",
    "saleNum": 0,
    "saleService": "一年包换",
    "sn": "No10001",
    "status": "1",
    "templateId": 42
  }
}

http://localhost:18081/spu/save

postman测试:成功

----------------------------------------------------------------------------------------------------------------------------------------------------------

根据ID查询商品

/***
 * 根据ID查询Goods
 * @param id
 * @return
 */
@GetMapping("/goods/{id}")
public Result<Goods> findGoodsById(@PathVariable Long id){
    //根据ID查询Goods(SPU+SKU)信息
    Goods goods = spuService.findGoodsById(id);
    return new Result<Goods>(true,StatusCode.OK,"查询成功",goods);
}


/***
 * 根据SPU的ID查找SPU以及对应的SKU集合
 * @param spuId
 */
Goods findGoodsById(Long spuId);


/***
 * 根据SpuID查询goods信息
 * @param spuId
 * @return
 */
@Override
public Goods findGoodsById(Long spuId) {
	//查询Spu
	Spu spu = spuMapper.selectByPrimaryKey(spuId);

	//查询List<Sku>
	Sku sku = new Sku();
	sku.setSpuId(spuId);
	List<Sku> skus = skuMapper.select(sku);
	//封装Goods
	Goods goods = new Goods();
	goods.setSkuList(skus);
	goods.setSpu(spu);
	return goods;
}

测试:http://localhost:18081/spu/goods/1400819467537088512

{
    "flag": true,
    "code": 20000,
    "message": "查询成功",
    "data": {
        "spu": {
            "id": 1400819467537088512,
            "sn": "No10001",
            "name": "华为高档手机",
            "caption": "华为手机大促销",
            "brandId": 8557,
            "category1Id": 1,
            "category2Id": 59,
            "category3Id": 64,
            "templateId": 42,
            "freightId": 0,
            "image": null,
            "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg",
            "saleService": "一年包换",
            "introduction": "华为产品世界最强",
            "specItems": "{\"颜色\":[\"红\",\"绿\"],\"机身内存\":[\"64G\",\"8G\"]}",
            "paraItems": "{\"赠品\":\"充电器\",\"出厂年份\":\"2019\"}",
            "saleNum": 0,
            "commentNum": 0,
            "isMarketable": "1",
            "isEnableSpec": "1",
            "isDelete": "0",
            "status": "1"
        },
        "skuList": [
            {
                "id": 1400819472301817856,
                "sn": "No1001",
                "name": "华为高档手机  红色  移动3G",
                "price": 1000,
                "num": 5,
                "alertNum": 10,
                "image": "http://www.baidu.com",
                "images": "",
                "weight": 0,
                "createTime": "2021-06-04T14:19:23.000+0000",
                "updateTime": "2021-06-04T14:19:23.000+0000",
                "spuId": 1400819467537088512,
                "categoryId": 64,
                "categoryName": "语言文字",
                "brandName": "华为",
                "spec": "{\"颜色\":\"红色\",\"网络\":\"移动3G\"}",
                "saleNum": 0,
                "commentNum": 0,
                "status": "1"
            }
        ]
    }
}

保存修改

修改changgou-service-goods的SpuServiceImpl的saveGoods方法,修改添加SPU部分代码:

if(spu.getId()==null){
    //增加
    spu.setId(idWorker.nextId());
    spuMapper.insertSelective(spu);
}else{
    //修改数据
    spuMapper.updateByPrimaryKeySelective(spu);
    //删除该Spu的Sku
    Sku sku = new Sku();
    sku.setSpuId(spu.getId());
    skuMapper.delete(sku);
}

测试:http://localhost:18081/spu/save

{

        "spu": {
            "id": 1401029000662351872,
            "sn": "No10001",
            "name": "华为高档手机20210605哈哈哈1999",
            "caption": "华为手机大促销",
            "brandId": 8557,
            "category1Id": 1,
            "category2Id": 59,
            "category3Id": 64,
            "templateId": 42,
            "freightId": 0,
            "image": null,
            "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg",
            "saleService": "一年包换",
            "introduction": "华为产品世界最强",
            "specItems": "{\"颜色\":[\"红\",\"绿\"],\"机身内存\":[\"64G\",\"8G\"]}",
            "paraItems": "{\"赠品\":\"充电器\",\"出厂年份\":\"2019\"}",
            "saleNum": 0,
            "commentNum": 0,
            "isMarketable": "1",
            "isEnableSpec": "1",
            "isDelete": "0",
            "status": "1"
        },
        "skuList": [
            {
                "id": 1400819472301817856,
                "sn": "No1001",
                "name": "华为高档手机  红色  移动3G",
                "price": 1000,
                "num": 5,
                "alertNum": 10,
                "image": "http://www.baidu.com",
                "images": "",
                "weight": 0,
                "createTime": "2021-06-04T14:19:23.000+0000",
                "updateTime": "2021-06-04T14:19:23.000+0000",
                "spuId": 1400819467537088512,
                "categoryId": 64,
                "categoryName": "语言文字",
                "brandName": "华为",
                "spec": "{\"颜色\":\"红色\",\"网络\":\"移动3G\"}",
                "saleNum": 0,
                "commentNum": 0,
                "status": "1"
            }
        ]

}

修改SKU库存

后面补充。。。。

商品审核

商品新增后,审核状态为0(未审核),默认为下架状态。

审核商品,需要校验是否是被删除的商品,如果未删除则修改审核状态为1,并自动上架

下架商品,需要校验是否是被删除的商品,如果未删除则修改上架状态为0

上架商品,需要审核通过的商品

/**
 * 审核
 * @param id
 * @return
 */
@PutMapping("/audit/{id}")
public Result audit(@PathVariable Long id){
    spuService.audit(id);
    return new Result(true,StatusCode.OK,"审核成功");
}

/***
 * 商品审核
 * @param spuId
 */
void audit(Long spuId);

/***
 * 商品审核
 * @param spuId
 */
@Override
public void audit(Long spuId) {
    //查询商品
    Spu spu = spuMapper.selectByPrimaryKey(spuId);
    //判断商品是否已经删除
    if(spu.getIsDelete().equalsIgnoreCase("1")){
        throw new RuntimeException("该商品已经删除!");
    }
    //实现上架和审核
    spu.setStatus("1"); //审核通过
    spu.setIsMarketable("1"); //上架
    spuMapper.updateByPrimaryKeySelective(spu);
}

下架商品

/**
 * 下架
 * @param id
 * @return
 */
@PutMapping("/pull/{id}")
public Result pull(@PathVariable Long id){
    spuService.pull(id);
    return new Result(true,StatusCode.OK,"下架成功");
}

/***
 * 商品下架
 * @param spuId
 */
void pull(Long spuId);

/**
 * 商品下架
 * @param spuId
 */
@Override
public void pull(Long spuId) {
    Spu spu = spuMapper.selectByPrimaryKey(spuId);
    if(spu.getIsDelete().equals("1")){
        throw new RuntimeException("此商品已删除!");
    }
    spu.setIsMarketable("0");//下架状态
    spuMapper.updateByPrimaryKeySelective(spu);
}

上架商品

/**
 * 商品上架
 * @param id
 * @return
 */
@PutMapping("/put/{id}")
public Result put(@PathVariable Long id){
    spuService.put(id);
    return new Result(true,StatusCode.OK,"上架成功");
}

/***
 * 商品上架
 * @param spuId
 */
void put(Long spuId);

/***
 * 商品上架
 * @param spuId
 */
@Override
public void put(Long spuId) {
    Spu spu = spuMapper.selectByPrimaryKey(spuId);
    //检查是否删除的商品
    if(spu.getIsDelete().equals("1")){
        throw new RuntimeException("此商品已删除!");
    }
    if(!spu.getStatus().equals("1")){
        throw new RuntimeException("未通过审核的商品不能!");
    }
    //上架状态
    spu.setIsMarketable("1");
    spuMapper.updateByPrimaryKeySelective(spu);
}

批量上架

前端传递一组商品ID,后端进行批量上下架处理

/**
 *  批量上架
 * @param ids
 * @return
 */
@PutMapping("/put/many")
public Result putMany(@RequestBody Long[] ids){
    int count = spuService.putMany(ids);
    return new Result(true,StatusCode.OK,"上架"+count+"个商品");
}


/**
 * 批量上架
 * @param ids
 * @return
 */
int putMany(Long[] ids);


/***
 * 批量上架
 * @param ids:需要上架的商品ID集合
 * @return
 */
@Override
public int putMany(Long[] ids) {
    Spu spu=new Spu();
    spu.setIsMarketable("1");//上架
    //update tb_spu set IsMarketable=1 where id in(ids) and isdelete=0 and is_marketable=0 and status=1
    Example example=new Example(Spu.class);
    Example.Criteria criteria = example.createCriteria();
    criteria.andIn("id", Arrays.asList(ids));//id
    //下架状态
    criteria.andEqualTo("isMarketable","0");
    //审核通过的
    criteria.andEqualTo("status","1");
    //非删除的
    criteria.andEqualTo("isDelete","0");
    return spuMapper.updateByExampleSelective(spu, example);
}

批量下架

/**
 *  批量下架
 * @param ids
 * @return
 */
@PutMapping("/pull/many")
public Result pullMany(@RequestBody Long[] ids){
    int count = spuService.pullMany(ids);
    return new Result(true,StatusCode.OK,count+"款商品下架成功");
}


/**
 * 批量下架
 * @param ids
 * @return
 */
int pullMany(Long[] ids);


/**
 * 批量下架
 * @param ids 需要下架的商品ID集合
 * @return
 */
@Override
public int pullMany(Long[] ids) {
    //is_marketable是否上架,0已下架,1已上架
    //is_delete是否删除,0:未删除,1:已删除
    //status审核状态,0:未审核,1:已审核,2:审核不通过
    //批量上架 update tb_spu set is_marketable=1 where id in(ids)and is_delete=0 and is_marketable=0 and status=1
    //批量下架 update tb_spu set is_marketable=0 where id in(ids) and is_delete=0 and is_marketable=1 and status=1

    Spu spu=new Spu();
    spu.setIsMarketable("0");//下架
    Example example=new Example(Spu.class);
    Example.Criteria criteria = example.createCriteria();
    criteria.andIn("id", Arrays.asList(ids));//id
    //上架状态
    criteria.andEqualTo("isMarketable","1");
    //审核通过的
    criteria.andEqualTo("status","1");
    //非删除的
    criteria.andEqualTo("isDelete","0");
    return spuMapper.updateByExampleSelective(spu, example);
}

启动EurekaApplication,启动GoodsApplication

postman测试批量上架:http://localhost:18081/spu/put/many

//is_marketable是否上架,0已下架,1已上架
//is_delete是否删除,0:未删除,1:已删除
//status审核状态,0:未审核,1:已审核,2:审核不通过

可以看到,这两条数据的状态改成了下架

postman测试批量下架:http://localhost:18081/spu/pull/many

----------------------------------------------------------------------------------------------------------------------------------------------------------

删除与还原商品

商品列表中的删除商品功能,并非真正的删除,而是将删除标记的字段设置为1,

在回收站中有恢复商品的功能,将删除标记的字段设置为0

在回收站中有删除商品的功能,是真正的物理删除。

实现思路

逻辑删除商品,修改spu表is_delete字段为1

商品回收站显示spu表is_delete字段为1的记录

回收商品,修改spu表is_delete字段为0

/**
 * 逻辑删除
 * @param id
 * @return
 */
@DeleteMapping("/logic/delete/{id}")
public Result logicDelete(@PathVariable Long id){
    spuService.logicDelete(id);
    return new Result(true,StatusCode.OK,"逻辑删除成功!");
}


/***
 * 逻辑删除
 * @param spuId
 */
void logicDelete(Long spuId);


/***
 * 逻辑删除
 * @param spuId
 */
@Override
@Transactional
public void logicDelete(Long spuId) {
    Spu spu = spuMapper.selectByPrimaryKey(spuId);
    //检查是否下架的商品
    if(!spu.getIsMarketable().equals("0")){
        throw new RuntimeException("必须先下架再删除!");
    }
    //删除
    spu.setIsDelete("1");
    //未审核
    spu.setStatus("0");
    spuMapper.updateByPrimaryKeySelective(spu);
}

还原被删除的商品

/**
 * 恢复数据
 * @param id
 * @return
 */
@PutMapping("/restore/{id}")
public Result restore(@PathVariable Long id){
    spuService.restore(id);
    return new Result(true,StatusCode.OK,"数据恢复成功!");
}


/***
 * 还原被删除商品
 * @param spuId
 */
void restore(Long spuId);


/**
 * 恢复数据
 * @param spuId
 */
@Override
public void restore(Long spuId) {
    Spu spu = spuMapper.selectByPrimaryKey(spuId);
    //检查是否删除的商品
    if(!spu.getIsDelete().equals("1")){
        throw new RuntimeException("此商品未删除!");
    }
    //未删除
    spu.setIsDelete("0");
    //未审核
    spu.setStatus("0");
    spuMapper.updateByPrimaryKeySelective(spu);
}

物理删除商品

修改com.changgou.goods.service.impl.SpuServiceImpl的delete方法,代码如下:

/**
 * 删除
 * @param id
 */
@Override
public void delete(Long id){
    Spu spu = spuMapper.selectByPrimaryKey(id);
    //检查是否被逻辑删除  ,必须先逻辑删除后才能物理删除
    if(!spu.getIsDelete().equals("1")){
        throw new RuntimeException("此商品不能删除!");
    }
    spuMapper.deleteByPrimaryKey(id);
}

商品列表代码生成器已经生成了

代码就不贴了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值