乐优商城(05)–商品管理
一、导入图片资源
现在商品表中虽然有数据,但是所有的图片信息都是无法访问的,因此需要把图片导入到服务器中:
将images.zip文件上传至/leyou/static
目录:在leyou下创建static目录
使用命令解压:
unzip images.zip
修改Nginx配置,使nginx反向代理这些图片地址:
vim /opt/nginx/config/nginx.conf
修改成如下配置:
server {
listen 80;
server_name image.leyou.com;
# 监听域名中带有group的,交给FastDFS模块处理
location ~/group([0-9])/ {
ngx_fastdfs_module;
}
# 将其它图片代理指向本地的/leyou/static目录
location / {
root /leyou/static/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
不要忘记重新加载nginx配置
nginx -s reload
二、商品查询
2.1、前端页面
先看整体页面结构(Goods.vue):
并且在Vue实例挂载后就会发起查询(mounted调用getDataFromServer方法初始化数据):
data中数据的修改:
2.2、后端实现
2.2.1、实体类
Spu
@Table(name = "tb_spu")
public class Spu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; //主键id
private String title; //标题
private String subTitle; //小标题
private Long cid1; //1级类目
private Long cid2; //2级类目
private Long cid3; //3级类目
private Long brandId; //品牌id
private Boolean saleable; //是否上架
private Boolean valid; //是否有效 逻辑删除
private Date createTime; //创建时间
private Date lastUpdateTime; //最后修改时间
//get和set
}
SpuDetail
@Table(name="tb_spu_detail")
public class SpuDetail {
@Id
private Long spuId;// 对应的SPU的id
private String description;// 商品描述
private String specialSpec;// 商品特殊规格的名称及可选值模板
private String genericSpec;// 商品的全局规格属性
private String packingList;// 包装清单
private String afterService;// 售后服务
// get和set
}
2.2.2、mapper
public interface SpuMapper extends Mapper<Spu> {
}
2.2.3、controller
-
请求方式:GET
-
请求路径:/spu/page
-
请求参数:
- page:当前页
- rows:每页大小
- key:过滤条件
- saleable:上架或下架
- sortBy:排序字段
-
返回结果:商品SPU的分页信息。
- 要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,新建一个类,继承SPU,并且拓展cname和bname属性,写到
leyou-item-interface
public class SpuBo extends Spu { private String cname; // 商品分类名称 private String bname; // 品牌名称 private SpuDetail spuDetail; //商品详情 private List<Sku> skus; //sku列表 //get和set }
这里提前贴上Sku的代码
@Table(name = "tb_sku") public class Sku { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //sku主键id private Long spuId; //spu的id private String title; //商品标题 private String images; //商品图片,会有多张,以,分隔 private Long price; //销售价格,以分为单位 private String indexes; //特有属性在spu中对应的下标 private String ownSpec; //商品特殊规格的键值对 private Boolean enable; //是否有效,逻辑删除用 private Date createTime; //创建时间 private Date lastUpdateTime; //最后修改时间 @Transient private Integer stock; //库存 //get和set }
- 要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,新建一个类,继承SPU,并且拓展cname和bname属性,写到
编写controller代码:
这里把与商品相关的一切业务接口都放到一起,起名为GoodsController,业务层也是这样
@RestController
public class GoodsController {
@Autowired
private GoodsService goodsService;
/**
* 根据查询条件分页并排序查询商品信息
* @param key
* @param saleable
* @param page
* @param rows
* @return
*/
@GetMapping("/spu/page")
public ResponseEntity<PageResult<SpuBo>> querySpuBoByPage(
@RequestParam(value = "key",required = false) String key,
@RequestParam(value = "saleable",required = false) Boolean saleable,
@RequestParam(value = "page",defaultValue = "1") Integer page,
@RequestParam(value = "rows",defaultValue = "5") Integer rows,
@RequestParam(value = "sortBy",required = false) String sortBy,
@RequestParam(value = "desc",required = false) Boolean desc
){
PageResult<SpuBo> pageResult = this.goodsService.querySpuBoByPage(key,saleable,page,rows,sortBy,desc);
if (CollectionUtils.isEmpty(pageResult.getItems())){
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(pageResult);
}
}
2.2.4、service
public interface GoodsService {
/**
* 根据查询条件分页并排序查询商品信息
* @param key
* @param saleable
* @param page
* @param rows
* @return
*/
PageResult<SpuBo> querySpuBoByPage(String key, Boolean saleable, Integer page, Integer rows,String sortBy,Boolean desc);
}
实现类:
@Service
public class GoodsServiceImpl implements GoodsService {
@Autowired
private SpuMapper spuMapper;
@Autowired
private CategoryService categoryService;
@Autowired
private BrandMapper brandMapper;
/**
* 根据查询条件分页并排序查询商品信息
*
* @param key
* @param saleable
* @param page
* @param rows
* @return
*/
@Override
public PageResult<SpuBo> querySpuBoByPage(String key, Boolean saleable, Integer page, Integer rows,