微信点餐系统02——买家端代码编写

Posted 老猫念诗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信点餐系统02——买家端代码编写相关的知识,希望对你有一定的参考价值。

一、买家端类目
1、创建实体类
​ 首先创建实体类,这里先创建买家类目表的实体类。

@Data
@Entity
@DynamicUpdate
public class ProductCategory {
    //类目id
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer categoryId;
    //类目名称
    private String categoryName;
    //类目种类
    private Integer categoryType;
    //类目创建时间
    private Date createTime;
    //类目更新时间
    private Date updateTime;

    public ProductCategory(Integer categoryId, String categoryName, Integer categoryType) {
        this.categoryId = categoryId;
        this.categoryName = categoryName;
        this.categoryType = categoryType;
    }

    public ProductCategory() {
    }

    @Override
    public String toString() {
        return "ProductCategory{" +
                "categoryId=" + categoryId +
                ", categoryName=\'" + categoryName + \'\\\'\' +
                ", categoryType=" + categoryType +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                \'}\';
    }
}

​ 这里注意类名及属性名要与数据库表一一对应,这个类中为了知道创建及更新时间,加入了时间参数,但是不是手动上传,而是自动更新的,所以要加上注解@DynamicUpdate。

​ 所以实际需要写的只有两个一个类目名称、一个类目类型,主键自增,写好这三个参数的构造方法,加上Getter和Setter方法,toString方法,把他们用@Entity设置成实体类,在竹简上加上@Id,并且设置为自增。

2、创建dao并测试
​ Dao写成接口继承Jpa的接口。这样就可以直接使用Jpa中的方法了。

​ 这里就要注意现实当中的业务场景了,查询类目类型,可以查询到所需要类型的List集合了。(就相当于把所有类目都查出来,但是也可能只查一部分)

public interface ProductCategoryRepository extends JpaRepository<ProductCategory,Integer> {
    List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);
}

​ 测试。点击类目右键GO TO TEST直接生成测试方法,如果不及时测试,报错都不知道是哪个环节有问题。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductCategoryRepositoryTest {

    @Autowired
    private ProductCategoryRepository repository;
    //测试保存
    @Test
    public void testSave(){
        ProductCategory productCategory = new ProductCategory();
        productCategory.setCategoryName("增肌必备");
        productCategory.setCategoryType(3);
        ProductCategory pro = repository.save(productCategory);
        Assert.assertNotEquals(0,pro);
    }
    //测试查找一个
    @Test
    public void testFind(){
        ProductCategory productCategory = repository.findById(1).get();
        Assert.assertNotNull(productCategory);
    }
    //测试更新
    @Test
    public void testUpdate(){
        ProductCategory productCategory = new ProductCategory();
        productCategory.setCategoryId(8);
        productCategory.setCategoryName("丰胸必备");
        productCategory.setCategoryType(6);
        ProductCategory pro = repository.save(productCategory);
        Assert.assertNotEquals(0,pro);
    }
    //测试查找多个
    @Test
    public void testFindByCategoryTypeIn(){
        List<Integer> categoryTypeList = new ArrayList<>();
        categoryTypeList.add(2);
        categoryTypeList.add(3);
        categoryTypeList.add(4);
        categoryTypeList.add(5);
        List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList);
        for (ProductCategory productCategory:byCategoryTypeIn){
            System.out.println(productCategory);
        }
    }

3、买家端service层
​ 这里就是业务相关了,查询所有类目用于卖家后台操作,新增类目、更新类目同理,查询一条类目后面可用于显示所有商品等等,查询多条类目可以用于给买家展示当前有什么活动等等,如男生最爱,热销榜等等类目。

​ 先写个service接口。

/**
 * 类目表的service层接口
 */
public interface ProductCategoryService {
    //查询一条
    ProductCategory findOne(Integer categoryId);

    //查询所有
    List<ProductCategory> findAll();

    //查询多条
    List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList);

    //新增和更新
    ProductCategory save(ProductCategory productCategory);
}

​ 再写其实现类。

@Service
//类目表的service层实现类
public class ProductCategoryServiceImpl implements ProductCategoryService {
    @Autowired
    private ProductCategoryRepository repository;

    @Override
    public ProductCategory findOne(Integer categoryId) {
        return repository.findById(categoryId).get();
    }

    @Override
    public List<ProductCategory> findAll() {
        return repository.findAll();
    }

    @Override
    public List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList) {
        return repository.findByCategoryTypeIn(categoryTypeList);
    }

    @Override
    public ProductCategory save(ProductCategory productCategory) {
        return repository.save(productCategory);
    }
}

​ 最后进行测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductCategoryRepositoryTest {

    @Autowired
    private ProductCategoryRepository repository;

    @Test
    public void testSave(){
        ProductCategory productCategory = new ProductCategory();
        productCategory.setCategoryName("增肌必备");
        productCategory.setCategoryType(3);
        ProductCategory pro = repository.save(productCategory);
        Assert.assertNotEquals(0,pro);
    }

    @Test
    public void testFind(){
        ProductCategory productCategory = repository.findById(1).get();
        Assert.assertNotNull(productCategory);
    }

    @Test
    public void testUpdate(){
        ProductCategory productCategory = new ProductCategory();
        productCategory.setCategoryId(8);
        productCategory.setCategoryName("丰胸必备");
        productCategory.setCategoryType(6);
        ProductCategory pro = repository.save(productCategory);
        Assert.assertNotEquals(0,pro);
    }

    @Test
    public void testFindByCategoryTypeIn(){
        List<Integer> categoryTypeList = new ArrayList<>();
        categoryTypeList.add(2);
        categoryTypeList.add(3);
        categoryTypeList.add(4);
        categoryTypeList.add(5);
        List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList);
        for (ProductCategory productCategory:byCategoryTypeIn){
            System.out.println(productCategory);
        }
    }
}

二、买家端商品
1、创建实体类
​ 买家端商品也一样,主要是商品的增删改查。

​ 生成产品的实体类

@Data
@Entity
public class ProductInfo {
    //商品id
    @Id
    private String productId;
    //商品名称
    private String productName;
    //商品价格
    private BigDecimal productPrice;
    //商品库存
    private Integer productStock;
    //商品描述
    private String productDescription;
    //商品小图
    private String productIcon;
    //商品类型
    private Integer productStatus;
    //所属类目类型
    private Integer categoryType;
    /*//创建时间
    private Date createTime;
    //更新时间
    private Date updateTime;*/
}

​ 因为它是String类型的id,所以不能自增。创建时间和更新时间先不写,加上@Entity注解和id。

2、创建dao并测试
​ 然后就是写Dao测试。

public interface ProductInfoRepository extends JpaRepository<ProductInfo,String> {
    //查询上架的商品
    List<ProductInfo> findByProductStatus(Integer productStatus);
}

​ 测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductInfoRepositoryTest {

    @Autowired
    private ProductInfoRepository repository;

    @Test
    public void testSave(){
        ProductInfo productInfo = new ProductInfo();
        productInfo.setProductId("123458");
        productInfo.setProductName("鱼翅炒饭");
        productInfo.setProductPrice(new BigDecimal(100.00));
        productInfo.setProductStock(12);
        productInfo.setProductDescription("鱼翅炒饭,尉迟炒的饭");
        productInfo.setProductIcon("http://xxx.jpg");
        productInfo.setCategoryType(3);
        ProductInfo prod = repository.save(productInfo);
        Assert.assertNotEquals(null,prod);
    }

    @Test
    public void findByProductStatus() {
        List<ProductInfo> productInfos = repository.findByProductStatus(2);
        productInfos.forEach(productInfo -> System.out.println(productInfo));
    }
}

3、买家端商品service层
​ 接口。

public interface ProductInfoService {
    //查询一个
    ProductInfo findOne(String productId);

    //查询所有的商品
    Page<ProductInfo> findAll(Pageable pageable);

    //查询所有在架的商品
    List<ProductInfo> findUpAll();

    //保存
    ProductInfo save(ProductInfo productInfo);

    //加库存
    //减库存
}

接口实现类。

@Service
public class ProductInfoServiceImpl implements ProductInfoService {
    @Autowired
    private ProductInfoRepository repository;

    @Override
    public ProductInfo findOne(String productId) {
        return repository.findById(productId).get();
    }

    @Override
    public Page<ProductInfo> findAll(Pageable pageable) {
        return repository.findAll(pageable);
    }

    @Override
    public List<ProductInfo> findUpAll() {
        return repository.findByProductStatus(ProductStatusEnum.UP.getCode());
    }

    @Override
    public ProductInfo save(ProductInfo productInfo) {
        return repository.save(productInfo);
    }
}

​ 测试方法。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductInfoServiceImplTest {
    @Autowired
    private ProductInfoServiceImpl service;

    @Test
    public void findOne() {
        ProductInfo productInfo = service.findOne("123456");
        Assert.assertEquals("123456",productInfo.getProductId());
    }

    @Test
    public void findAll() {
        PageRequest request = PageRequest.of(0,2);
        Page<ProductInfo> productInfos = service.findAll(request);
        Assert.assertNotEquals(0,productInfos.getSize());
    }

    @Test
    public void findUpAll() {
        List<ProductInfo> pr = service.findUpAll();
        pr.forEach(productInfo -> System.out.println(productInfo));
    }

    @Test
    public void save() {
        ProductInfo productInfo = new ProductInfo();
        productInfo.setProductId("123459");
        productInfo.setProductName("减肥餐");
        productInfo.setProductPrice(new BigDecimal(20.9));
        productInfo.setProductStock(100);
        productInfo.setProductDescription("减肥餐,一顿减10斤");
        productInfo.setProductIcon("http://xxxxxxx.jpg");
        productInfo.setProductStatus(0);
        productInfo.setCategoryType(0);
        ProductInfo productInfo1 = service.save(productInfo);
        Assert.assertNotEquals(null,productInfo1);
    }
}

三、api
​ 写完这两层就该写前后端接口的对应了,本示例前端提供了商品的对应api,如果想实现前后端对应的话,就要按照这个方式来传递数据。

GET /sell/buyer/product/list
{
    "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",
                }
            ]
        }
    ]
}

​ 这里分析一下,外层一个code、msg、还有一个data的数组。data中包含类目名称、类目类型、还有该类目下的所有商品、商品又包括id编号、名称、价格、描述和图片。所以按照这个写即可。

1、最外层
​ 最外层也就是code、msg、data的数据。为了方便传输,创建一个返回前端的对象。这里如果一下子都写了太麻烦了,一层一层逻辑不好分清,所以先写个最外层ResultVO类(VO就是view object的简写)。

/**
 * http请求返回的最外层对象
 */
@Data
public class ResultVO<T> {
    //code错误码
    private Integer code;

    //msg
    private String msg;

    //对象
    private T data;
}

​ 然后写个controller并访问。

@RestController
@RequestMapping("/buyer/product")
public class BuyerProductController {

    @RequestMapping("/list")
    public ResultVO list(){
        ResultVO resultVO = new ResultVO();
        return resultVO;
    }
}

​ 因为api中说了要访问/sell/buyer/product/list地址,controller中少了一层/sell,所以我们在yaml中配置一下前面的路径。

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://192.168.1.9:3306/sell?characterEncoding=utf-8&userSSL=false
  jpa:
    show-sql: true
server:
  port: 8081
  servlet:
    context-path: /sell    #主要是配置这个

​ 这样启动并测试。为了让浏览器解析数据为json格式可以下载相关插件。

2、中间层
​ 这样最外层就有了,下面该写中间层了,看一下上面Json格式中间层是项目的类目层。

​ 中间层是类目层。还是老规矩,写个ProductVo类。

/**
 * 其实是商品包含类目层
 */
@Data
public class ProductVO {
    @JsonProperty("name")
    private String categoryName;

    @JsonProperty("type")
    private Integer categoryType;

    @JsonProperty("food")
    private List<ProductInfoVO> productInfoVOList;
}

3、最内层

/**
 * 商品详情
 */
@Data
public class ProductInfoVO {

    @JsonProperty("id")
    private String productId;

    @JsonProperty("name")
    private String productName;

    @JsonProperty("price")
    private BigDecimal productPrice;

    @JsonProperty
    private String productDescription;

    @JsonProperty("icon")
    private String productIcon;
}

​ 这样写完以后,把他们关联起来并测试。

​ 原代码改进如下:添加了一些数据进行测试。

@RequestMapping("/list")
public ResultVO list(){
    ResultVO resultVO = new ResultVO();
    ProductVO productVO = new ProductVO();
    ProductInfoVO productInfoVO = new ProductInfoVO();

    productInfoVO.setProductId("123456");
    productInfoVO.setProductName("皮蛋瘦肉粥");
    productInfoVO.setProductPrice(new BigDecimal(11.00));
    productInfoVO.setProductDescription("赵谦孙李,粥无阵亡");
    productInfoVO.setProductIcon("http:xxxx.jsp");

    resultVO.setCode(0);
    resultVO.setMsg("成功");
    resultVO.setData(productVO);

    productVO.setCategoryName("热销榜");
    productVO.setCategoryType(2);
    productVO.setProductInfoVOList(Arrays.asList(productInfoVO));

    return resultVO;
}

​ 测试结果如下(忘了截图了,基本就是这个样子):
​ 这样测试完成后说明我们可以通过这个进行传递json数据给前端了。
4、查询数据库传递给json对象
​ json的道路搭建好之后,就该传递真正的数据了,也就是把数据传递给controller。

@RestController
@RequestMapping("/buyer/product")
public class BuyerProductController {
    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private ProductCategoryService productCategoryService;

    @RequestMapping("/list")
    public ResultVO list(){
        //1、查询所有的上架商品
        List<ProductInfo> productInfoUpAll = productInfoService.findUpAll();

        //2、查询类目(要一次性查询)
        List<Integer> categoryTypeList = productInfoUpAll.stream().map(e -> e.getCategoryType()).collect(Collectors.toList());
        List<ProductCategory> productCategoryList = productCategoryService.findByCategoryTypeIn(categoryTypeList);

        //3、数据拼装
        List<ProductVO> productVOList = new ArrayList<>();
        for (ProductCategory productCategory:productCategoryList){
            ProductVO productVO = new ProductVO();
            productVO.setCategoryName(productCategory.getCategoryName());
            productVO.setCategoryType(productCategory.getCategoryType());

            List<ProductInfoVO> productInfoVOList = new ArrayList<>();
            for (ProductInfo productInfo:productInfoUpAll){
                //下面这步要好好理解
                if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) {
                    ProductInfoVO productInfoVO = new ProductInfoVO();
                    //productInfoVO.setProductId(productInfo.getProductId());
                    //productInfoVO.setProductName(productInfo.getProductName());
                    //productInfoVO.setProductPrice(productInfo.getProductPrice());
                    //productInfoVO.setProductDescription(productInfo.getProductDescription());
                    //productInfoVO.setProductIcon(productInfo.getProductIcon());
                    BeanUtils.copyProperties(productInfo,productInfoVO);
                    productInfoVOList.add(productInfoVO);
                }
            }
            productVO.setProductInfoVOList(productInfoVOList);
            productVOList.add(productVO);
        }

        ResultVO resultVO = ResultVOUtil.success(productVOList);
        return resultVO;
    }
}

​ 分层查询数据,并拼装起来传给json。这里为了方便不用每次都创建ResultVO对象(因为没什么区别,步骤一样),创建了ResultVOUtils工具类。

public class ResultVOUtil {

    public static ResultVO success(Object object){
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(0);
        resultVO.setMsg("成功");
        resultVO.setData(object);
        return resultVO;
    }

    public static ResultVO success(){
        return success(null);
    }

    public static ResultVO error(Integer code,String msg){
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(code);
        resultVO.setMsg(msg);
        return resultVO;
    }
}

​ 分别创建了它的传递成功方法、传递失败方法。

​ 查询果然查到了,如上面那张图。

5、和前端连接显示页面
​ 这里就需要以前连接的虚拟机了,虚拟机ip地址是192.168.1.9,连接这个网址,可以连上,但是会立刻跳转到失败页面,因为这时相当于没有登陆。

​ 这里如果想登陆需要传递openid的值,所以随便传递一个即可,先登陆一个不跳转的页面,192.168.1.9/#/order,在console控制台中写document.cookie=‘openid=abc123’,这样就传递了一个值用来证明已经登陆。

​ 这时再登陆192.168.1.9,发现显示了页面。

​ 这时候访问不到是因为访问的是虚拟机的地址,在虚拟机中修改nginx为自己本机电脑的ip地址。

​ vim /usr/local/nginx/conf/nginx.conf

​ 在配置文件中修改。

​ 这样就可以访问了。

以上是关于微信点餐系统02——买家端代码编写的主要内容,如果未能解决你的问题,请参考以下文章

微信点餐系统-买家端新增商品和类目

微信点餐系统(-)

Spring Boot企业微信点餐系统 视频教程

微信点餐系统-卖家端通用功能和上下架

微信点餐系统-卖家端订单

java Spring Boot企业微信点餐系统