SpringBoot 企业微信点餐系统实战三:商品信息及买家商品api开发

gfgy 2018-08-20

SpringBoot 企业微信点餐系统实战三:商品信息及买家商品api开发

一、商品信息

1.1 商品信息 dto

按照数据库的字段写出对应的实体类 ProductInfo。@Data 是 lombok 的注解,用于自动生成 getter, setter, toString方法,不懂的可以自行查询相关资料。

@Entity

@Data

public class ProductInfo {

@Id

private String productId;

//商品名字

private String productName;

//商品价格

private BigDecimal productPrice;

//商品库存

private Integer productStock;

//商品描述

private String productDescription;

//商品状态

private Integer productStatus;

//商品图标

private String productIcon;

//商品类目编号

private Integer categoryType;

public ProductInfo() {

}

}

1.2 商品信息repository

新加了一个方法 findByProductStatus,根据商品的状态查询商品列表,用于查询所有上架商品。

package com.solo.sell.repository;

import com.solo.sell.dto.ProductInfo;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import java.util.List;

@Repository

public interface ProductInfoRepository extends JpaRepository<ProductInfo, String>{

List<ProductInfo> findByProductStatus(Integer status);

}

1.3 商品信息 service

暂时先想到以下几个方法,做到后面不够了再加。加库存和减库存后面再实现。

package com.solo.sell.service;

import com.solo.sell.dto.ProductInfo;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;

import java.util.List;

public interface ProductInfoService {

/**

* 通过id查询单个商品

* @param id

* @return

*/

ProductInfo findById(String id);

/**

* 查询上架的产品

* @return

*/

List<ProductInfo> findUpAll();

/**

* 查询所有商品 带分页

* @param pageable

* @return

*/

Page<ProductInfo> findAll(Pageable pageable);

/**

* 保存一个商品

* @param productInfo

* @return

*/

ProductInfo save(ProductInfo productInfo);

//加库存

//减库存

}

实现类 ProductInfoServiceImpl

package com.solo.sell.service.impl;

import com.solo.sell.dto.ProductInfo;

import com.solo.sell.enums.ProductStatusEnum;

import com.solo.sell.repository.ProductInfoRepository;

import com.solo.sell.service.ProductInfoService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class ProductInfoServiceImpl implements ProductInfoService {

@Autowired

private ProductInfoRepository repository;

@Override

public ProductInfo findById(String id) {

return repository.findById(id).get();

}

@Override

public List<ProductInfo> findUpAll() {

return repository.findByProductStatus(ProductStatusEnum.UP.getCode());

}

@Override

public Page<ProductInfo> findAll(Pageable pageable) {

return repository.findAll(pageable);

}

@Override

public ProductInfo save(ProductInfo productInfo) {

return repository.save(productInfo);

}

}

二、商品信息测试

商品信息的 repository 和 service 都写完了,养成好习惯,别忘了测试。

2.1 repository 测试

@RunWith(SpringRunner.class)

@SpringBootTest

public class ProductInfoRepositoryTest {

@Autowired

private ProductInfoRepository repository;

@Test

public void add(){

ProductInfo info = new ProductInfo();

info.setProductId("haha123");

info.setProductName("酸菜鱼");

info.setProductPrice(new BigDecimal(36));

info.setProductDescription("好吃的酸菜鱼,不可错过");

info.setProductIcon("http://abc.png");

info.setProductStatus(0);

info.setProductStock(10);

info.setCategoryType(3);

ProductInfo result = repository.save(info);

Assert.assertNotNull(result);

}

@Test

public void findOne(){

ProductInfo info = repository.findById("haha123").get();

Assert.assertEquals("haha123", info.getProductId());

}

@Test

public void findByProductStatus() {

List<ProductInfo> list = repository.findByProductStatus(0);

Assert.assertNotEquals(0, list.size());

}

}

2.2 service 测试

@RunWith(SpringRunner.class)

@SpringBootTest

public class ProductInfoServiceImplTest {

@Autowired

private ProductInfoServiceImpl service;

@Test

public void findById() {

ProductInfo info = service.findById("haha123");

Assert.assertEquals("haha123", info.getProductId());

}

@Test

public void findUpAll() {

List<ProductInfo> all = service.findUpAll();

Assert.assertNotEquals(0, all.size());

}

@Test

public void findAll() {

PageRequest pageRequest = PageRequest.of(0, 3);

Page<ProductInfo> productInfoPage = service.findAll(pageRequest);

Assert.assertNotEquals(0, productInfoPage.getTotalElements());

}

@Test

public void save() {

ProductInfo info = new ProductInfo();

info.setProductId("haha456");

info.setProductName("皮皮虾");

info.setProductPrice(new BigDecimal(49));

info.setProductDescription("皮皮虾我们走");

info.setProductIcon("http://abc.png");

info.setProductStatus(0);

info.setProductStock(99);

info.setCategoryType(4);

ProductInfo save = service.save(info);

Assert.assertNotNull(save);

}

}

SpringBoot 企业微信点餐系统实战三:商品信息及买家商品api开发

三、买家商品 api 开发

商品分类和商品信息开发完之后,就可以开发买家 api 了。

买家最简单的一个需求就是查询上架商品列表,先实现这个功能。

3.1 返回结果分析

本来返回的数据格式应该是后端定的,但这个项目是先有的前端,已经规定好了数据格式,看看数据格式是什么样的吧

{

"code": 0,

"msg": "成功",

"data": [

{

"name": "热榜",

"type": 1,

"foods": [

{

"id": "123456",

"name": "皮蛋粥",

"price": 1.2,

"description": "好吃的皮蛋粥",

"icon": "http://xxx.com",

}

]

},

{

"name": "好吃的",

"type": 2,

"foods": [

{

"id": "123457",

"name": "慕斯蛋糕",

"price": 10.9,

"description": "美味爽口",

"icon": "http://xxx.com",

}

]

}

]

}

先约定一下所有返回给前端的对象都放在 VO 包下,对象名以 VO结尾便于区分。猜测 VO 应该是 view object 的缩写吧…

返回结果有三层对象,最外层应该是整个项目统一的数据结构,我们定义为 ResultVO。data 字段里先是商品分类 ProdoctVO,然后每个分类里的 foods 字段才是具体商品 ProductInfoVO。

统一返回结果 ResultVO

package com.solo.sell.VO;

import lombok.Data;

/**

* 返回的统一结果格式

* @param <T>

*/

@Data

public class ResultVO<T> {

/** 状态码 */

private Integer code;

/** 返回信息 */

private String msg;

/** 返回数据 */

private T data;

public ResultVO() {}

}

返回商品对象 ProductVO

package com.solo.sell.VO;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

import java.util.List;

/**

* 商品信息(包含类目)

*/

@Data

public class ProductVO {

@JsonProperty("name")

private String categoryName;

@JsonProperty("type")

private Integer categoryType;

@JsonProperty("foods")

private List<ProductInfoVO> productInfoVOList ;

}

属性名尽量起的一看就知道是什么,不要只是叫 name,时间久了不知道具体指哪个name 了。

但返回的数据就叫 name 怎么办呢?在属性上面加个注解 @JsonProperty("name") ,这样对应的属性名就是 name 了。

返回的商品信息 ProductInfoVO

package com.solo.sell.VO;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

import java.math.BigDecimal;

@Data

public class ProductInfoVO {

@JsonProperty("id")

private String productId;

@JsonProperty("name")

private String productName;

@JsonProperty("price")

private BigDecimal productPrice;

@JsonProperty("description")

private String productDescription;

@JsonProperty("icon")

private String productIcon;

}

3.2 买家商品 controller

返回结果格式知道了,就开始写 controller 逻辑啦。

所有的 controller 都放在 controller 包下,新建 controller 包,然后新建 BuyerProductController

package com.solo.sell.controller;

import com.solo.sell.VO.ProductInfoVO;

import com.solo.sell.VO.ProductVO;

import com.solo.sell.VO.ResultVO;

import com.solo.sell.dto.ProductCategory;

import com.solo.sell.dto.ProductInfo;

import com.solo.sell.service.ProductCategoryService;

import com.solo.sell.service.ProductInfoService;

import com.solo.sell.utils.ResultVOUtils;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;

import org.springframework.beans.BeanUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;

import java.util.List;

import java.util.stream.Collectors;

@RestController

@RequestMapping("/buyer/product")

@Api("买家端获取商品")

public class BuyerProductController {

@Autowired

private ProductInfoService productInfoService;

@Autowired

private ProductCategoryService categoryService;

@ApiOperation(value = "获取所有上架商品", notes = "获取所有上架商品,下架商品除外")

@RequestMapping(value = "/list", method = RequestMethod.GET)

public ResultVO list() {

// 1.查询所有上架商品

List<ProductInfo> productInfoList = productInfoService.findUpAll();

// 2.查询类目(一次性查询)

//用 java8 的特性获取到上架商品的所有类型

List<Integer> categoryTypes = productInfoList.stream().map(e -> e.getCategoryType()).collect(Collectors.toList());

List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(categoryTypes);

List<ProductVO> productVOList = new ArrayList<>();

//数据拼装

for (ProductCategory category : productCategoryList) {

ProductVO productVO = new ProductVO();

//属性拷贝

BeanUtils.copyProperties(category, productVO);

//把类型匹配的商品添加进去

List<ProductInfoVO> productInfoVOList = new ArrayList<>();

for (ProductInfo productInfo : productInfoList) {

if (productInfo.getCategoryType().equals(category.getCategoryType())) {

ProductInfoVO productInfoVO = new ProductInfoVO();

BeanUtils.copyProperties(productInfo, productInfoVO);

productInfoVOList.add(productInfoVO);

}

}

productVO.setProductInfoVOList(productInfoVOList);

productVOList.add(productVO);

}

return ResultVOUtils.success(productVOList);

}

}

注释写的比较详细就不多解释了,就是按照前端要求的格式把数据拼接在一起。

@Api 和 @ApiOperation 注解可以先不用管,这是集成了 swagger , 调试接口更加方便。下篇文章会专门讲 swagger 和 Spring Boot 的整合。

3.3 验证

打开浏览器,输入地址 http://127.0.0.1:8080/sell/buyer/product/list 可以看到正确返回了数据

SpringBoot 企业微信点餐系统实战三:商品信息及买家商品api开发

以上就是本节的内容,下期见~

转移源码地址:https://github.com/cachecats/sell

相关推荐