乐趣区

关于java:微信点餐系统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

​ 在配置文件中批改。

​ 这样就能够拜访了。

退出移动版