微信点餐系统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——买家端代码编写的主要内容,如果未能解决你的问题,请参考以下文章