admin管理员组文章数量:1600155
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 | ||
name | SPU名 | VARCHAR | ||
caption | 副标题 | VARCHAR | ||
brand_id | 品牌ID | INT | ||
category1_id | 一级分类 | INT | ||
category2_id | 二级分类 | INT | ||
category3_id | 三级分类 | INT | ||
template_id | 模板ID | INT | ||
freight_id | 运费模板id | INT | ||
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 | 商品id | BIGINT | ||
sn | 商品条码 | VARCHAR | ||
name | SKU名称 | VARCHAR | ||
price | 价格(分) | INT | ||
num | 库存数量 | INT | ||
alert_num | 库存预警数量 | INT | ||
image | 商品图片 | VARCHAR | ||
images | 商品图片列表 | VARCHAR | ||
weight | 重量(克) | INT | ||
create_time | 创建时间 | DATETIME | ||
update_time | 更新时间 | DATETIME | ||
spu_id | SPUID | BIGINT | ||
category_id | 类目ID | INT | ||
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/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/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对象,
将Spu
和List<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",
"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/image/1.jpg,http://www.qingcheng/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/image/1.jpg,http://www.qingcheng/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",
"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/image/1.jpg,http://www.qingcheng/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",
"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);
}
商品列表代码生成器已经生成了
代码就不贴了
版权声明:本文标题:商城-商品发布(代码生成器的使用) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1728335801a1154767.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论