微信点餐系统(二)买家订单操作 一、创建订单 二、查看订单列表 三、查看订单详情 四、取消订单

买家端的订单操作主要有创建订单,查看订单,查看订单详情,取消订单四个操作。

1.查看API文档

###创建订单

```
POST /sell/buyer/order/create
```

参数

```
name: "张三"
phone: "18868822111"
address: "慕课网总部"
openid: "ew3euwhd7sjw9diwkq" //用户的微信openid
items: [{
    productId: "1423113435324",
    productQuantity: 2 //购买数量
}]

```

返回

```
{
  "code": 0,
  "msg": "成功",
  "data": {
      "orderId": "147283992738221" 
  }
}
```

根据API文档可以知道前端发送的请求是POST请求,请求路径是 /sell/buyer/order/create

根据文档中传入参数编写一个OrderForm类,接收前端传入数据。注意传入有关订单部分的数据items是个列表,每个元素只有productId和productQuantity,而没有有关价格、库存等其它数据,这是为了保证安全性。这些字段还要求非空否则就会报错。

 1 package club.nipengfei.sell1.form;
 2 
 3 import lombok.Data;
 4 import javax.validation.constraints.NotEmpty;
 5 
 6 @Data
 7 public class OrderForm {
 8     @NotEmpty(message = "姓名必填")
 9     private String name;
10 
11     @NotEmpty(message = "手机号必填")
12     private String phone;
13 
14     @NotEmpty(message = "地址必填")
15     private String address;
16 
17     @NotEmpty(message = "openid必填")
18     private String openid;
19 
20     @NotEmpty(message = "购物车不为空")
21     private String items;
22 }
OrderForm

 返回的data参数可以看作一个Map<String,String>集合。

2.开发repository层(dao层)

数据库中与订单有关的表有如下两张:

微信点餐系统(二)买家订单操作
一、创建订单
二、查看订单列表
三、查看订单详情
四、取消订单

先在repository包下的OrderMasterRepository接口下新建一个sava方法用向order_master表保存数据。再在repository包下的OrderDetailRepository接口下新建一个save方法用来向order_detail表保存数据。

 1 package club.nipengfei.sell1.repository;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderMaster;
 4 import org.apache.ibatis.annotations.Insert;
 5 import org.apache.ibatis.annotations.Mapper;
 6 import org.apache.ibatis.annotations.Select;
 7 import org.apache.ibatis.annotations.Update;
 8 import org.springframework.stereotype.Repository;
 9 
10 import java.util.List;
11 
12 @Repository
13 @Mapper
14 public interface OrderMasterRepository {
15 
16     @Select("select * from order_master where buyer_openid=#{buyerOpenid}")
17     List<OrderMaster> findByBuyerOpenid(String buyerOpenid);
18 
19     @Insert("insert into order_master (order_id,buyer_name,buyer_phone,buyer_address,buyer_openid,order_amount,order_status,pay_status) values(#{order_id},#{buyer_name},#{buyer_phone},#{buyer_address},#{buyer_openid},#{order_amount},#{order_status},#{pay_status})")
20     void save(OrderMaster orderMaster);
21 
22     @Select("select * from order_master where order_id=#{order_id}")
23     OrderMaster findOne(String order_id);
24 
25     @Update("update order_master set order_status=#{order_status} where order_id=#{order_id}")
26     void updateOrderMasterStatus(OrderMaster orderMaster);
27 
28     @Update("update order_master set pay_status=#{pay_status} where order_id=#{order_id}")
29     void updateOrderMasterPayStatus(OrderMaster orderMaster);
30 }
OrderMasterRepository
 1 package club.nipengfei.sell1.repository;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderDetail;
 4 import org.apache.ibatis.annotations.Insert;
 5 import org.apache.ibatis.annotations.Mapper;
 6 import org.apache.ibatis.annotations.Select;
 7 import org.springframework.stereotype.Repository;
 8 
 9 import java.util.List;
10 
11 @Repository
12 @Mapper
13 public interface OrderDetailRepository {
14 
15     @Select("select * from order_detail where order_id=#{orderId}")
16     List<OrderDetail> findByOrderId(String orderId);
17 
18     @Insert("insert into order_detail (detail_id,order_id,product_id,product_name,product_price,product_quantity,product_icon) values(#{detail_id},#{order_id},#{product_id},#{product_name},#{product_price},#{product_quantity},#{product_icon})")
19     void save(OrderDetail orderDetail);
20 }
OrderDetailRepository

显然根据OrderFrom类中的数据是不充分的,比如没有order_amount订单总价字段信息等 。因此在service层需要计算相应的总价,这部分在service再写。

在order_detail表中有product_name、product_icon等字段,这些信息需要根据前端的productId查询完整的产品信息在保存到order_detail表中。

3.开发controller层

新建一个OrderDTO类,用来封装根据OrderForm前端传入的表单数查询出更加详细的信息。使用Gson将orderForm中的字符串转为List<OrderDetail>

 1 package club.nipengfei.sell1.dto;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderDetail;
 4 import club.nipengfei.sell1.utils.serializer.Date2LongSerializer;
 5 import com.fasterxml.jackson.annotation.JsonInclude;
 6 import com.fasterxml.jackson.annotation.JsonProperty;
 7 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 8 import lombok.Data;
 9 
10 import java.math.BigDecimal;
11 import java.util.Date;
12 import java.util.List;
13 
14 @Data
15 // @JsonInclude(JsonInclude.Include.NON_NULL)   // 当为null值时不返回该字段
16 public class OrderDTO {
17 
18     @JsonProperty("orderId")
19     private String order_id;
20 
21     @JsonProperty("buyerName")
22     private String buyer_name;
23 
24     @JsonProperty("buyerPhone")
25     private String buyer_phone;
26 
27     @JsonProperty("buyerAddress")
28     private String buyer_address;
29 
30     @JsonProperty("buyerOpenid")
31     private String buyer_openid;
32 
33     @JsonProperty("orderAmount")
34     private BigDecimal order_amount;
35 
36     /** 订单状态 默认0新订单 */
37     @JsonProperty("orderStatus")
38     private Integer order_status;
39 
40     /** 支付状态 默认0等待支付 */
41     @JsonProperty("payStatus")
42     private Integer pay_status;
43 
44     @JsonProperty("createTime")
45     @JsonSerialize(using = Date2LongSerializer.class)
46     private Date create_time;
47 
48     @JsonProperty("updateTime")
49     @JsonSerialize(using = Date2LongSerializer.class)
50     private Date update_time;
51 
52     List<OrderDetail> orderDetailList;
53 }
OrderDTO
 1 package club.nipengfei.sell1.converter;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderDetail;
 4 import club.nipengfei.sell1.dataobject.OrderDetail1;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import com.google.gson.Gson;
10 import com.google.gson.reflect.TypeToken;
11 import lombok.extern.slf4j.Slf4j;
12 
13 import java.util.ArrayList;
14 import java.util.List;
15 
16 @Slf4j
17 public class OrderForm2OrderDTOConverter {
18 
19     public static OrderDTO convert(OrderForm orderForm){
20         Gson gson = new Gson();
21         OrderDTO orderDTO = new OrderDTO();
22         orderDTO.setBuyer_name(orderForm.getName());
23         orderDTO.setBuyer_phone(orderForm.getPhone());
24         orderDTO.setBuyer_address(orderForm.getAddress());
25         orderDTO.setBuyer_openid(orderForm.getOpenid());
26 
27         List<OrderDetail1> orderDetailList1 = new ArrayList<>();
28         List<OrderDetail> orderDetailList = new ArrayList<>();
29 
30         try {
31             orderDetailList1 = gson.fromJson(orderForm.getItems(),new TypeToken<List<OrderDetail1>>(){}.getType());
32             for (OrderDetail1 orderDetail1 : orderDetailList1) {
33                 OrderDetail o1 = new OrderDetail();
34                 o1.setProduct_id(orderDetail1.getProductId());
35                 o1.setProduct_quantity(orderDetail1.getProductQuantity());
36                 orderDetailList.add(o1);
37             }
38 
39         }catch (Exception e){
40             log.error("【对象转换】错误,String={}",orderForm.getItems());
41             throw new SellException(ResultEnum.PARAM_ERROR);
42         }
43         orderDTO.setOrderDetailList(orderDetailList);
44 
45         return orderDTO;
46 
47     }
48 }
OrderForm2OrderDTOConverter
 1 package club.nipengfei.sell1.controller;
 2 
 3 import club.nipengfei.sell1.VO.ResultVO;
 4 import club.nipengfei.sell1.converter.OrderForm2OrderDTOConverter;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import club.nipengfei.sell1.service.BuyerService;
10 import club.nipengfei.sell1.service.OrderService;
11 import club.nipengfei.sell1.utils.ResultVOUtil;
12 import com.github.pagehelper.PageInfo;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.util.CollectionUtils;
16 import org.springframework.util.ResourceUtils;
17 import org.springframework.util.StringUtils;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.web.bind.annotation.*;
20 
21 import javax.validation.Valid;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 @RestController
27 @RequestMapping("/buyer/order")
28 @Slf4j
29 public class BuyerOrderController {
30 
31     @Autowired
32     private OrderService orderService;
33 
34     @Autowired
35     private BuyerService buyerService;
36 
37     // 创建订单
38     @PostMapping("/create")
39     public ResultVO<Map<String,String>> create(@Valid OrderForm orderForm, BindingResult bindingResult){
40 
41         if(bindingResult.hasErrors()){
42             log.error("【创建订单】参数不正确,orderForm={}",orderForm);
43             throw new SellException(ResultEnum.PARAM_ERROR.getCode(),bindingResult.getFieldError().getDefaultMessage());
44         }
45 
46         OrderDTO orderDTO = OrderForm2OrderDTOConverter.convert(orderForm);
47 
48         if(CollectionUtils.isEmpty(orderDTO.getOrderDetailList())){
49             log.error("【创建订单】购物车为空");
50             throw new SellException(ResultEnum.CART_EMPTY);
51         }
52 
53         OrderDTO createResult = orderService.create(orderDTO);
54 
55         Map<String,String> map = new HashMap<>();
56         map.put("orderId",createResult.getOrder_id());
57 
58         return ResultVOUtil.success(map);
59     }
60 }
BuyerOrderController

根据API文档返回给前端的数据主体数据只有orderId。

4.开发service层

  1. 查询商品的数量
  2. 计算出订单总价
  3. 将订单数据写入orderMaster和orderDetail表中
  4. 扣库存
 1 package club.nipengfei.sell1.service.impl;
 2 
 3 import club.nipengfei.sell1.converter.OrderMaster2OrderDTOConverter;
 4 import club.nipengfei.sell1.dataobject.OrderDetail;
 5 import club.nipengfei.sell1.dataobject.OrderMaster;
 6 import club.nipengfei.sell1.dataobject.ProductInfo;
 7 import club.nipengfei.sell1.dto.CartDTO;
 8 import club.nipengfei.sell1.dto.OrderDTO;
 9 import club.nipengfei.sell1.enums.OrderStatusEnum;
10 import club.nipengfei.sell1.enums.PayStatusEnum;
11 import club.nipengfei.sell1.enums.ResultEnum;
12 import club.nipengfei.sell1.exception.SellException;
13 import club.nipengfei.sell1.repository.OrderDetailRepository;
14 import club.nipengfei.sell1.repository.OrderMasterRepository;
15 import club.nipengfei.sell1.service.OrderService;
16 import club.nipengfei.sell1.service.ProductService;
17 import club.nipengfei.sell1.utils.KeyUtil;
18 import com.github.pagehelper.PageHelper;
19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.BeanUtils;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.util.CollectionUtils;
25 
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.stream.Collector;
31 import java.util.stream.Collectors;
32 
33 @Service
34 @Slf4j
35 public class OrderServiceImpl implements OrderService{
36 
37     @Autowired
38     private ProductService productService;
39 
40     @Autowired
41     private OrderDetailRepository orderDetailRepository;
42 
43     @Autowired
44     private OrderMasterRepository orderMasterRepository;
45 
46     @Override
47     @Transactional
48     public OrderDTO create(OrderDTO orderDTO) {
49 
50         String orderId = KeyUtil.genUniqueKey();
51         BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
52         List<CartDTO> cartDTOList = new ArrayList<>();
53 
54         // 1.查询商品数量
55         for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
56             ProductInfo productInfo = productService.findOne(orderDetail.getProduct_id());
57             if(productInfo==null){
58                 throw new SellException(ResultEnum.PRODUCT_NOT_EXIT);
59             }
60             // 2.计算订单总价
61             orderAmount = productInfo.getProduct_price().multiply(new BigDecimal(orderDetail.getProduct_quantity())).add(orderAmount);
62             // 订单详情入库
63             orderDetail.setDetail_id(KeyUtil.genUniqueKey());
64             orderDetail.setOrder_id(orderId);
65             BeanUtils.copyProperties(productInfo,orderDetail);
66             orderDetailRepository.save(orderDetail);
67 
68             CartDTO cartDTO = new CartDTO(orderDetail.getProduct_id(),orderDetail.getProduct_quantity());
69 
70             cartDTOList.add(cartDTO);
71 
72         }
73         // 3.写入订单数据库(orderMaster和orderDetail)
74         OrderMaster orderMaster = new OrderMaster();
75         // 注意需要先拷贝,防止null值覆盖
76         orderDTO.setOrder_id(orderId);
77         BeanUtils.copyProperties(orderDTO,orderMaster);
78         orderMaster.setOrder_amount(orderAmount);
79         orderMaster.setOrder_status(OrderStatusEnum.NEW.getCode());
80         orderMaster.setPay_status(PayStatusEnum.WAIT.getCode());
81 
82         orderMasterRepository.save(orderMaster);
83 
84         // 4.扣库存
85         productService.decreaseStock(cartDTOList);
86 
87         return orderDTO;
88     }
89 }
OrderServiceImpl

该service方法主要是将数据完整的写入到两张订单表中,注意需要扣库存,防止相应产品的数量不够。

二、查看订单列表

1.查看API文档

###订单列表

```
GET /sell/buyer/order/list
```

参数

```
openid: 18eu2jwk2kse3r42e2e
page: 1 //从第1页开始
size: 10
```

返回

```
{
  "code": 0,
  "msg": "成功",
  "data": [
    {
      "orderId": "161873371171128075",
      "buyerName": "张三",
      "buyerPhone": "18868877111",
      "buyerAddress": "慕课网总部",
      "buyerOpenid": "18eu2jwk2kse3r42e2e",
      "orderAmount": 0,
      "orderStatus": 0,
      "payStatus": 0,
      "createTime": 1490171219,
      "updateTime": 1490171219,
      "orderDetailList": null
    },
    {
      "orderId": "161873371171128076",
      "buyerName": "张三",
      "buyerPhone": "18868877111",
      "buyerAddress": "慕课网总部",
      "buyerOpenid": "18eu2jwk2kse3r42e2e",
      "orderAmount": 0,
      "orderStatus": 0,
      "payStatus": 0,
      "createTime": 1490171219,
      "updateTime": 1490171219,
      "orderDetailList": null
    }]
}
```

根据API文档可以知道前端发送的请求是GET请求,请求路径是 /sell/buyer/order/list

传入的参数有page,size表示需要进行分页操作,这里使用mybatis的分页插件PageHelper。

返回的data数据是List<OrderDTO>

2.开发repository层

根据openid从order_Master表中查询出相应信息

 1 package club.nipengfei.sell1.repository;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderMaster;
 4 import org.apache.ibatis.annotations.Insert;
 5 import org.apache.ibatis.annotations.Mapper;
 6 import org.apache.ibatis.annotations.Select;
 7 import org.apache.ibatis.annotations.Update;
 8 import org.springframework.stereotype.Repository;
 9 
10 import java.util.List;
11 
12 @Repository
13 @Mapper
14 public interface OrderMasterRepository {
15 
16     @Select("select * from order_master where buyer_openid=#{buyerOpenid}")
17     List<OrderMaster> findByBuyerOpenid(String buyerOpenid);
18 
19 }
OrderMasterRepository

3.开发service层

由于使用了分页插件需要引入坐标:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
PageHelper坐标

在调用repository方法之前使用PageHelper.startPage(page,size);会在执行的sql语句后面加上limit语句

 1 package club.nipengfei.sell1.service.impl;
 2 
 3 import club.nipengfei.sell1.converter.OrderMaster2OrderDTOConverter;
 4 import club.nipengfei.sell1.dataobject.OrderDetail;
 5 import club.nipengfei.sell1.dataobject.OrderMaster;
 6 import club.nipengfei.sell1.dataobject.ProductInfo;
 7 import club.nipengfei.sell1.dto.CartDTO;
 8 import club.nipengfei.sell1.dto.OrderDTO;
 9 import club.nipengfei.sell1.enums.OrderStatusEnum;
10 import club.nipengfei.sell1.enums.PayStatusEnum;
11 import club.nipengfei.sell1.enums.ResultEnum;
12 import club.nipengfei.sell1.exception.SellException;
13 import club.nipengfei.sell1.repository.OrderDetailRepository;
14 import club.nipengfei.sell1.repository.OrderMasterRepository;
15 import club.nipengfei.sell1.service.OrderService;
16 import club.nipengfei.sell1.service.ProductService;
17 import club.nipengfei.sell1.utils.KeyUtil;
18 import com.github.pagehelper.PageHelper;
19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.BeanUtils;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.util.CollectionUtils;
25 
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.stream.Collector;
31 import java.util.stream.Collectors;
32 
33 @Service
34 @Slf4j
35 public class OrderServiceImpl implements OrderService{
36 
37     @Autowired
38     private ProductService productService;
39 
40     @Autowired
41     private OrderDetailRepository orderDetailRepository;
42 
43     @Autowired
44     private OrderMasterRepository orderMasterRepository;
45 
46     @Override
47     public List<OrderDTO> findList(String buyerOpenid, int page, int size) {
48         PageHelper.startPage(page,size);
49         List<OrderMaster> orderMasterList = orderMasterRepository.findByBuyerOpenid(buyerOpenid);
50         List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterList);
51         return orderDTOList;
52     }
53 
54 }
OrderServiceImpl

4.开发controller层

 1 package club.nipengfei.sell1.controller;
 2 
 3 import club.nipengfei.sell1.VO.ResultVO;
 4 import club.nipengfei.sell1.converter.OrderForm2OrderDTOConverter;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import club.nipengfei.sell1.service.BuyerService;
10 import club.nipengfei.sell1.service.OrderService;
11 import club.nipengfei.sell1.utils.ResultVOUtil;
12 import com.github.pagehelper.PageInfo;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.util.CollectionUtils;
16 import org.springframework.util.ResourceUtils;
17 import org.springframework.util.StringUtils;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.web.bind.annotation.*;
20 
21 import javax.validation.Valid;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 @RestController
27 @RequestMapping("/buyer/order")
28 @Slf4j
29 public class BuyerOrderController {
30 
31     @Autowired
32     private OrderService orderService;
33 
34     @Autowired
35     private BuyerService buyerService;
36 
37     // 订单列表
38     @GetMapping("/list")
39     public ResultVO<List<OrderDTO>> list(@RequestParam("openid") String openid,@RequestParam(value = "page",defaultValue = "1") Integer page,@RequestParam(value = "size",defaultValue = "10") Integer size){
40         if(StringUtils.isEmpty(openid)){
41             log.error("【查询订单列表】openid为空");
42             throw new SellException(ResultEnum.PARAM_ERROR);
43         }
44 
45         List<OrderDTO> list = orderService.findList(openid, page, size);
46         // PageInfo pageInfo = new PageInfo(list);
47         return ResultVOUtil.success(list);
48 
49     }
50 
51 }
BuyerOrderController

三、查看订单详情

1.查看API文档

###查询订单详情

```
GET /sell/buyer/order/detail
```

参数

```
openid: 18eu2jwk2kse3r42e2e
orderId: 161899085773669363
```

返回

```
{
    "code": 0,
    "msg": "成功",
    "data": {
          "orderId": "161899085773669363",
          "buyerName": "李四",
          "buyerPhone": "18868877111",
          "buyerAddress": "慕课网总部",
          "buyerOpenid": "18eu2jwk2kse3r42e2e",
          "orderAmount": 18,
          "orderStatus": 0,
          "payStatus": 0,
          "createTime": 1490177352,
          "updateTime": 1490177352,
          "orderDetailList": [
            {
                "detailId": "161899085974995851",
                "orderId": "161899085773669363",
                "productId": "157875196362360019",
                "productName": "招牌奶茶",
                "productPrice": 9,
                "productQuantity": 2,
                "productIcon": "http://xxx.com",
                "productImage": "http://xxx.com"
            }
        ]
    }
}
```

根据API文档可以知道前端发送的请求是GET请求,请求路径是 /sell/buyer/order/detail

传入的参数有openid和orderId。查看订单详情需要openid是为了安全性,只有当根据orderId查出的openid与传入的参数的openid一致时才能查看。

返回参数data是OrderDTO

2.开发repository层

 1 package club.nipengfei.sell1.controller;
 2 
 3 import club.nipengfei.sell1.VO.ResultVO;
 4 import club.nipengfei.sell1.converter.OrderForm2OrderDTOConverter;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import club.nipengfei.sell1.service.BuyerService;
10 import club.nipengfei.sell1.service.OrderService;
11 import club.nipengfei.sell1.utils.ResultVOUtil;
12 import com.github.pagehelper.PageInfo;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.util.CollectionUtils;
16 import org.springframework.util.ResourceUtils;
17 import org.springframework.util.StringUtils;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.web.bind.annotation.*;
20 
21 import javax.validation.Valid;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 @RestController
27 @RequestMapping("/buyer/order")
28 @Slf4j
29 public class BuyerOrderController {
30 
31     @Autowired
32     private OrderService orderService;
33 
34     @Autowired
35     private BuyerService buyerService;
36 
37     // 订单详情
38     @GetMapping("/detail")
39     public ResultVO<OrderDTO> detail(@RequestParam("openid") String openid,@RequestParam("orderId") String orderId){
40 
41         OrderDTO orderDTO = buyerService.findOrderOne(openid, orderId);
42 
43         return ResultVOUtil.success(orderDTO);
44     }
45 }
BuyerOrderController

3.开发service层

 1 package club.nipengfei.sell1.service.impl;
 2 
 3 import club.nipengfei.sell1.dto.OrderDTO;
 4 import club.nipengfei.sell1.enums.ResultEnum;
 5 import club.nipengfei.sell1.exception.SellException;
 6 import club.nipengfei.sell1.service.BuyerService;
 7 import club.nipengfei.sell1.service.OrderService;
 8 import lombok.extern.slf4j.Slf4j;
 9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.stereotype.Service;
11 
12 @Service
13 @Slf4j
14 public class BuyerServiceImpl implements BuyerService {
15 
16     @Autowired
17     private OrderService orderService;
18 
19     @Override
20     public OrderDTO findOrderOne(String openid, String orderId) {
21 
22         return checkOrderOwner(openid,orderId);
23     }
24 
25     @Override
26     public OrderDTO cancelOrder(String openid, String orderId) {
27         OrderDTO orderDTO = checkOrderOwner(openid,orderId);
28         if(orderDTO==null){
29             log.error("【取消订单】查不到该订单orderId={}",orderId);
30             throw new SellException(ResultEnum.ORDER_NOT_EXIST);
31         }
32         return orderService.cancel(orderDTO);
33     }
34 
35     private OrderDTO checkOrderOwner(String openid, String orderId){
36         OrderDTO orderDTO = orderService.findOne(orderId);
37         if(orderDTO==null) return null;
38         // 判断是否是自己的订单
39         if (!orderDTO.getBuyer_openid().equalsIgnoreCase(openid)){
40             log.error("【查询订单】订单的openid不一致,openid={},orderDTO={}",openid,orderDTO);
41             throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
42         }
43         return orderDTO;
44     }
45 }
BuyerServiceImpl
  1 package club.nipengfei.sell1.service.impl;
  2 
  3 import club.nipengfei.sell1.converter.OrderMaster2OrderDTOConverter;
  4 import club.nipengfei.sell1.dataobject.OrderDetail;
  5 import club.nipengfei.sell1.dataobject.OrderMaster;
  6 import club.nipengfei.sell1.dataobject.ProductInfo;
  7 import club.nipengfei.sell1.dto.CartDTO;
  8 import club.nipengfei.sell1.dto.OrderDTO;
  9 import club.nipengfei.sell1.enums.OrderStatusEnum;
 10 import club.nipengfei.sell1.enums.PayStatusEnum;
 11 import club.nipengfei.sell1.enums.ResultEnum;
 12 import club.nipengfei.sell1.exception.SellException;
 13 import club.nipengfei.sell1.repository.OrderDetailRepository;
 14 import club.nipengfei.sell1.repository.OrderMasterRepository;
 15 import club.nipengfei.sell1.service.OrderService;
 16 import club.nipengfei.sell1.service.ProductService;
 17 import club.nipengfei.sell1.utils.KeyUtil;
 18 import com.github.pagehelper.PageHelper;
 19 import lombok.extern.slf4j.Slf4j;
 20 import org.springframework.beans.BeanUtils;
 21 import org.springframework.beans.factory.annotation.Autowired;
 22 import org.springframework.stereotype.Service;
 23 import org.springframework.transaction.annotation.Transactional;
 24 import org.springframework.util.CollectionUtils;
 25 
 26 import java.math.BigDecimal;
 27 import java.math.BigInteger;
 28 import java.util.ArrayList;
 29 import java.util.List;
 30 import java.util.stream.Collector;
 31 import java.util.stream.Collectors;
 32 
 33 @Service
 34 @Slf4j
 35 public class OrderServiceImpl implements OrderService{
 36 
 37     @Autowired
 38     private ProductService productService;
 39 
 40     @Autowired
 41     private OrderDetailRepository orderDetailRepository;
 42 
 43     @Autowired
 44     private OrderMasterRepository orderMasterRepository;
 45 
 46     @Override
 47     @Transactional
 48     public OrderDTO create(OrderDTO orderDTO) {
 49 
 50         String orderId = KeyUtil.genUniqueKey();
 51         BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
 52         List<CartDTO> cartDTOList = new ArrayList<>();
 53 
 54         // 1.查询商品数量
 55         for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
 56             ProductInfo productInfo = productService.findOne(orderDetail.getProduct_id());
 57             if(productInfo==null){
 58                 throw new SellException(ResultEnum.PRODUCT_NOT_EXIT);
 59             }
 60             // 2.计算订单总价
 61             orderAmount = productInfo.getProduct_price().multiply(new BigDecimal(orderDetail.getProduct_quantity())).add(orderAmount);
 62             // 订单详情入库
 63             orderDetail.setDetail_id(KeyUtil.genUniqueKey());
 64             orderDetail.setOrder_id(orderId);
 65             BeanUtils.copyProperties(productInfo,orderDetail);
 66             orderDetailRepository.save(orderDetail);
 67 
 68             CartDTO cartDTO = new CartDTO(orderDetail.getProduct_id(),orderDetail.getProduct_quantity());
 69 
 70             cartDTOList.add(cartDTO);
 71 
 72         }
 73         // 3.写入订单数据库(orderMaster和orderDetail)
 74         OrderMaster orderMaster = new OrderMaster();
 75         // 注意需要先拷贝,防止null值覆盖
 76         orderDTO.setOrder_id(orderId);
 77         BeanUtils.copyProperties(orderDTO,orderMaster);
 78         orderMaster.setOrder_amount(orderAmount);
 79         orderMaster.setOrder_status(OrderStatusEnum.NEW.getCode());
 80         orderMaster.setPay_status(PayStatusEnum.WAIT.getCode());
 81 
 82         orderMasterRepository.save(orderMaster);
 83 
 84         // 4.扣库存
 85         productService.decreaseStock(cartDTOList);
 86 
 87         return orderDTO;
 88     }
 89 
 90     @Override
 91     public OrderDTO findOne(String orderId) {
 92 
 93         OrderMaster orderMaster = orderMasterRepository.findOne(orderId);
 94         if(orderMaster==null){
 95             throw new SellException(ResultEnum.ORDER_NOT_EXIST);
 96         }
 97         List<OrderDetail> orderDetailList = orderDetailRepository.findByOrderId(orderId);
 98         if(CollectionUtils.isEmpty(orderDetailList)){
 99             throw new SellException(ResultEnum.ORDERDETAIL_NOT_EXIST);
100         }
101         OrderDTO orderDTO = new OrderDTO();
102         BeanUtils.copyProperties(orderMaster,orderDTO);
103         orderDTO.setOrderDetailList(orderDetailList);
104         return orderDTO;
105     }
106 
107     @Override
108     public List<OrderDTO> findList(String buyerOpenid, int page, int size) {
109         PageHelper.startPage(page,size);
110         List<OrderMaster> orderMasterList = orderMasterRepository.findByBuyerOpenid(buyerOpenid);
111         List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterList);
112         return orderDTOList;
113     }
114 
115     @Override
116     @Transactional
117     public OrderDTO cancel(OrderDTO orderDTO) {
118 
119         OrderMaster orderMaster = new OrderMaster();
120 
121 
122         // 判断订单状态
123         if(!orderDTO.getOrder_status().equals(OrderStatusEnum.NEW.getCode())){
124             log.error("【取消订单】订单状态不正确,orderId={},orderStatus={}",orderDTO.getOrder_id(),orderDTO.getOrder_status());
125             throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
126         }
127 
128         // 修改订单状态
129         orderDTO.setOrder_status(OrderStatusEnum.CANCEL.getCode());
130         BeanUtils.copyProperties(orderDTO,orderMaster);
131         orderMasterRepository.updateOrderMasterStatus(orderMaster);
132         OrderMaster one = orderMasterRepository.findOne(orderMaster.getOrder_id());
133         if(one==null||one.getOrder_status()!=2){
134             log.error("【取消订单】更新失败,orderMaster={}",one);
135             throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
136         }
137 
138         // 返还库存
139         if (CollectionUtils.isEmpty(orderDTO.getOrderDetailList())){
140             log.error("【取消订单】订单中无商品,orderDTO={}",orderDTO);
141             throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
142         }
143         List<CartDTO> cartDTOList = orderDTO.getOrderDetailList().stream().map(e -> new CartDTO(e.getProduct_id(),e.getProduct_quantity())).collect(Collectors.toList());
144         productService.increaseStock(cartDTOList);
145         // 如果已支付需要退款
146         if (orderDTO.getPay_status().equals(PayStatusEnum.SUCCESS.getCode())){
147             // TODO
148         }
149         return orderDTO;
150     }
151 
152     @Override
153     @Transactional
154     public OrderDTO finish(OrderDTO orderDTO) {
155         // 判断订单状态
156         if (!orderDTO.getOrder_status().equals(OrderStatusEnum.NEW.getCode())){
157             log.error("【完结订单】订单状态不正确,orderId={},orderStatus={}",orderDTO.getOrder_id(),orderDTO.getOrder_status());
158             throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
159         }
160 
161         // 修改订单状态
162         orderDTO.setOrder_status(OrderStatusEnum.FINISHED.getCode());
163         OrderMaster orderMaster = new OrderMaster();
164         BeanUtils.copyProperties(orderDTO,orderMaster);
165         orderMasterRepository.updateOrderMasterStatus(orderMaster);
166         OrderMaster one = orderMasterRepository.findOne(orderMaster.getOrder_id());
167         if(one==null||one.getOrder_status()!=1){
168             log.error("【完结订单】更新失败,orderMaster={}",one);
169             throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
170         }
171 
172         return orderDTO;
173     }
174 
175     @Override
176     @Transactional
177     public OrderDTO paid(OrderDTO orderDTO) {
178         // 判断订单状态
179         if (!orderDTO.getPay_status().equals(PayStatusEnum.WAIT.getCode())){
180             log.error("【完结订单】订单状态不正确,orderId={},orderPayStatus={}",orderDTO.getOrder_id(),orderDTO.getPay_status());
181             throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
182         }
183 
184         // 判断支付状态
185         if (!orderDTO.getPay_status().equals(PayStatusEnum.WAIT.getCode())){
186             log.error("【订单支付完成】订单支付状态不正确,orderDTO={}",orderDTO);
187             throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);
188         }
189 
190         // 修改支付状态
191         orderDTO.setPay_status(PayStatusEnum.SUCCESS.getCode());
192         OrderMaster orderMaster = new OrderMaster();
193         BeanUtils.copyProperties(orderDTO,orderMaster);
194         orderMasterRepository.updateOrderMasterPayStatus(orderMaster);
195         OrderMaster one = orderMasterRepository.findOne(orderMaster.getOrder_id());
196         if(one==null||one.getPay_status()!=1){
197             log.error("【订单支付完成】更新失败,orderMaster={}",one);
198             throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
199         }
200 
201         return orderDTO;
202     }
203 }
OrderServiceImpl

4.开发controller

 1 package club.nipengfei.sell1.controller;
 2 
 3 import club.nipengfei.sell1.VO.ResultVO;
 4 import club.nipengfei.sell1.converter.OrderForm2OrderDTOConverter;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import club.nipengfei.sell1.service.BuyerService;
10 import club.nipengfei.sell1.service.OrderService;
11 import club.nipengfei.sell1.utils.ResultVOUtil;
12 import com.github.pagehelper.PageInfo;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.util.CollectionUtils;
16 import org.springframework.util.ResourceUtils;
17 import org.springframework.util.StringUtils;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.web.bind.annotation.*;
20 
21 import javax.validation.Valid;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 @RestController
27 @RequestMapping("/buyer/order")
28 @Slf4j
29 public class BuyerOrderController {
30 
31     @Autowired
32     private OrderService orderService;
33 
34     @Autowired
35     private BuyerService buyerService;
36 
37     // 订单详情
38     @GetMapping("/detail")
39     public ResultVO<OrderDTO> detail(@RequestParam("openid") String openid,@RequestParam("orderId") String orderId){
40 
41         OrderDTO orderDTO = buyerService.findOrderOne(openid, orderId);
42 
43         return ResultVOUtil.success(orderDTO);
44     }
45 
46 }
BuyerOrderController

四、取消订单

1.查看API文档

###取消订单

```
POST /sell/buyer/order/cancel
```

参数

```
openid: 18eu2jwk2kse3r42e2e
orderId: 161899085773669363
```

返回

```
{
    "code": 0,
    "msg": "成功",
    "data": null
}
```

根据API文档可以知道前端发送的请求是POST请求,请求路径是 /sell/buyer/order/cancel

传入的参数有openid和orderId。

2.开发controller层

 1 package club.nipengfei.sell1.controller;
 2 
 3 import club.nipengfei.sell1.VO.ResultVO;
 4 import club.nipengfei.sell1.converter.OrderForm2OrderDTOConverter;
 5 import club.nipengfei.sell1.dto.OrderDTO;
 6 import club.nipengfei.sell1.enums.ResultEnum;
 7 import club.nipengfei.sell1.exception.SellException;
 8 import club.nipengfei.sell1.form.OrderForm;
 9 import club.nipengfei.sell1.service.BuyerService;
10 import club.nipengfei.sell1.service.OrderService;
11 import club.nipengfei.sell1.utils.ResultVOUtil;
12 import com.github.pagehelper.PageInfo;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.util.CollectionUtils;
16 import org.springframework.util.ResourceUtils;
17 import org.springframework.util.StringUtils;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.web.bind.annotation.*;
20 
21 import javax.validation.Valid;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 @RestController
27 @RequestMapping("/buyer/order")
28 @Slf4j
29 public class BuyerOrderController {
30 
31     @Autowired
32     private OrderService orderService;
33 
34     @Autowired
35     private BuyerService buyerService;
36 
37     // 取消订单
38     @PostMapping("/cancel")
39     public ResultVO cancel(@RequestParam("openid") String openid,@RequestParam("orderId") String orderId){
40         buyerService.cancelOrder(openid, orderId);
41         return ResultVOUtil.success();
42     }
43 }
BuyerOrderController

3.开发service层

  1. 判断订单状态,如果订单不是新建的,那么就抛出异常,提示订单状态不正确
  2. 修改订单状态至取消
  3. 返还库存
 1 package club.nipengfei.sell1.service.impl;
 2 
 3 import club.nipengfei.sell1.converter.OrderMaster2OrderDTOConverter;
 4 import club.nipengfei.sell1.dataobject.OrderDetail;
 5 import club.nipengfei.sell1.dataobject.OrderMaster;
 6 import club.nipengfei.sell1.dataobject.ProductInfo;
 7 import club.nipengfei.sell1.dto.CartDTO;
 8 import club.nipengfei.sell1.dto.OrderDTO;
 9 import club.nipengfei.sell1.enums.OrderStatusEnum;
10 import club.nipengfei.sell1.enums.PayStatusEnum;
11 import club.nipengfei.sell1.enums.ResultEnum;
12 import club.nipengfei.sell1.exception.SellException;
13 import club.nipengfei.sell1.repository.OrderDetailRepository;
14 import club.nipengfei.sell1.repository.OrderMasterRepository;
15 import club.nipengfei.sell1.service.OrderService;
16 import club.nipengfei.sell1.service.ProductService;
17 import club.nipengfei.sell1.utils.KeyUtil;
18 import com.github.pagehelper.PageHelper;
19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.BeanUtils;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.util.CollectionUtils;
25 
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.stream.Collector;
31 import java.util.stream.Collectors;
32 
33 @Service
34 @Slf4j
35 public class OrderServiceImpl implements OrderService{
36 
37     @Autowired
38     private ProductService productService;
39 
40     @Autowired
41     private OrderDetailRepository orderDetailRepository;
42 
43     @Autowired
44     private OrderMasterRepository orderMasterRepository;
45 
46     @Override
47     @Transactional
48     public OrderDTO cancel(OrderDTO orderDTO) {
49 
50         OrderMaster orderMaster = new OrderMaster();
51 
52 
53         // 判断订单状态
54         if(!orderDTO.getOrder_status().equals(OrderStatusEnum.NEW.getCode())){
55             log.error("【取消订单】订单状态不正确,orderId={},orderStatus={}",orderDTO.getOrder_id(),orderDTO.getOrder_status());
56             throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
57         }
58 
59         // 修改订单状态
60         orderDTO.setOrder_status(OrderStatusEnum.CANCEL.getCode());
61         BeanUtils.copyProperties(orderDTO,orderMaster);
62         orderMasterRepository.updateOrderMasterStatus(orderMaster);
63         OrderMaster one = orderMasterRepository.findOne(orderMaster.getOrder_id());
64         if(one==null||one.getOrder_status()!=2){
65             log.error("【取消订单】更新失败,orderMaster={}",one);
66             throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
67         }
68 
69         // 返还库存
70         if (CollectionUtils.isEmpty(orderDTO.getOrderDetailList())){
71             log.error("【取消订单】订单中无商品,orderDTO={}",orderDTO);
72             throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
73         }
74         List<CartDTO> cartDTOList = orderDTO.getOrderDetailList().stream().map(e -> new CartDTO(e.getProduct_id(),e.getProduct_quantity())).collect(Collectors.toList());
75         productService.increaseStock(cartDTOList);
76         // 如果已支付需要退款
77         if (orderDTO.getPay_status().equals(PayStatusEnum.SUCCESS.getCode())){
78             // TODO
79         }
80         return orderDTO;
81     }
82 
83 }
OrderServiceImpl

4.开发repository层

 1 package club.nipengfei.sell1.repository;
 2 
 3 import club.nipengfei.sell1.dataobject.ProductInfo;
 4 import com.github.pagehelper.Page;
 5 import org.apache.ibatis.annotations.Insert;
 6 import org.apache.ibatis.annotations.Mapper;
 7 import org.apache.ibatis.annotations.Select;
 8 import org.apache.ibatis.annotations.Update;
 9 import org.springframework.stereotype.Repository;
10 
11 import java.util.List;
12 
13 @Repository
14 @Mapper
15 public interface ProductInfoRepository {
16 
17     @Select("select * from product_info where product_status=#{productStatus}")
18     List<ProductInfo> findByProductStatus(Integer productStatus);
19 
20     @Insert("insert into product_info(product_id,product_name,product_price,product_stock,product_description,product_icon,product_status,category_type) values(#{product_id},#{product_name},#{product_price},#{product_stock},#{product_description},#{product_icon},#{product_status},#{category_type})")
21     void save(ProductInfo productInfo);
22 
23     @Select("select * from product_info where product_id=#{productId}")
24     ProductInfo findOne(String productId);
25 
26     @Select("select * from product_info")
27     List<ProductInfo> findAll();
28 
29     @Update("update product_info set product_stock=#{product_stock} where product_id=#{product_id}")
30     void updateProductStock(ProductInfo productInfo);
31 }
ProductInfoRepository
 1 package club.nipengfei.sell1.repository;
 2 
 3 import club.nipengfei.sell1.dataobject.OrderMaster;
 4 import org.apache.ibatis.annotations.Insert;
 5 import org.apache.ibatis.annotations.Mapper;
 6 import org.apache.ibatis.annotations.Select;
 7 import org.apache.ibatis.annotations.Update;
 8 import org.springframework.stereotype.Repository;
 9 
10 import java.util.List;
11 
12 @Repository
13 @Mapper
14 public interface OrderMasterRepository {
15 
16     @Select("select * from order_master where buyer_openid=#{buyerOpenid}")
17     List<OrderMaster> findByBuyerOpenid(String buyerOpenid);
18 
19     @Insert("insert into order_master (order_id,buyer_name,buyer_phone,buyer_address,buyer_openid,order_amount,order_status,pay_status) values(#{order_id},#{buyer_name},#{buyer_phone},#{buyer_address},#{buyer_openid},#{order_amount},#{order_status},#{pay_status})")
20     void save(OrderMaster orderMaster);
21 
22     @Select("select * from order_master where order_id=#{order_id}")
23     OrderMaster findOne(String order_id);
24 
25     @Update("update order_master set order_status=#{order_status} where order_id=#{order_id}")
26     void updateOrderMasterStatus(OrderMaster orderMaster);
27 
28     @Update("update order_master set pay_status=#{pay_status} where order_id=#{order_id}")
29     void updateOrderMasterPayStatus(OrderMaster orderMaster);
30 }
OrderMasterRepository