4、订单

来源:互联网 发布:幼儿英语教学软件 编辑:程序博客网 时间:2024/05/16 17:25

1、订单的两个实体类

订单的主表,是对应到用户的订单信息

@Entity@Data@DynamicUpdatepublic class OrderMaster {    /** 订单id. */    @Id    private String orderId;    /** 买家名字. */    private String buyerName;    /** 买家手机号. */    private String buyerPhone;    /** 买家地址. */    private String buyerAddress;    /** 买家微信Openid. */    private String buyerOpenid;    /** 订单总金额. */    private BigDecimal orderAmount;    /** 订单状态, 默认为0新下单. */    private Integer orderStatus = OrderStatusEnum.NEW.getCode();    /** 支付状态, 默认为0未支付. */    private Integer payStatus = PayStatusEnum.WAIT.getCode();    /** 创建时间. */    private Date createTime;    /** 更新时间. */    private Date updateTime;}

订单的详细表,是对应到每个订单中的详细信息

@Entity@Datapublic class OrderDetail {    @Id    private String detailId;    /** 订单id. */    private String orderId;    /** 商品id. */    private String productId;    /** 商品名称. */    private String productName;    /** 商品单价. */    private BigDecimal productPrice;    /** 商品数量. */    private Integer productQuantity;    /** 商品小图. */    private String productIcon;}

2、对这两个实体创建dao层进行测试。

public interface OrderMasterDao extends JpaRepository<OrderMaster,String>{    Page<OrderMaster> findByBuyerOpenid(String openid, Pageable pageable);}
public interface OrderDetailDao extends JpaRepository<OrderDetail,String>{    List<OrderDetail> findByOrderId(String orderid);}

对于测试都省略了,后面开始着重重视设计,至于dao层的测试与前面讲的商品一样。

3、service层开发:

接口:

public interface OrderService{    /**创建订单*/    OrderDto create(OrderDto orderDto);    /**根据order_id查询单个订单*/    OrderDto findOne(String orderid);    /**查询某个用户的订单列表*/    Page<OrderDto> findListByOpenid(String openid, Pageable pageable);    /**取消订单*/    OrderDto cancel(OrderDto orderDto);    /**完结订单*/    OrderDto finish(OrderDto orderDto);    /**支付订单*/    OrderDto paid(OrderDto orderDto);    /**查询所有的订单列表*/    Page<OrderDto> findList(Pageable pageable);}

3.1 创建订单:

@Override@Transactionalpublic OrderDto create(OrderDto orderDto) {    String orderid = KeyUtil.genUniqueKey();    BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);    //1、根据前端传来的商品id查询商品的单价、库存等信息    List<OrderDetail> orderDetailList = orderDto.getOrderDetailList();    for(OrderDetail orderDetail:orderDetailList){        ProductInfo productInfo = productService.findProductById(orderDetail.getProductId());        if(productInfo == null){            throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);        }        //2、拿到了对应的商品,我们就可以根据商品的单价和购买的数量算的总价了        orderAmount = productInfo.getProductPrice()                            .multiply(new BigDecimal(orderDetail.getProductQuantity()))                            .add(orderAmount);        //3、订单详情入库        orderDetail.setDetailId(KeyUtil.genUniqueKey());        orderDetail.setOrderId(orderid);        BeanUtils.copyProperties(productInfo,orderDetail);        orderDetailDao.save(orderDetail);    }    //4、订单主表入库    OrderMaster orderMaster = new OrderMaster();    orderDto.setOrderId(orderid);    BeanUtils.copyProperties(orderDto,orderMaster);    orderMaster.setOrderAmount(orderAmount);    orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());    orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());    orderMasterDao.save(orderMaster);    //5、扣库存    List<CartDTO> cartDTOList = orderDto.getOrderDetailList().stream()                                .map(e -> new CartDTO(e.getProductId(),e.getProductQuantity()))                                .collect(Collectors.toList());    productService.decreaseStock(cartDTOList);    return orderDto;}

扣库存这一块:

@Override@Transactionalpublic void decreaseStock(List<CartDTO> cartDTOList) {    //1、首先是遍历他,获得产品的id和对应的购买数量    for(CartDTO cartDTO:cartDTOList){        ProductInfo productInfo = productInfoDao.findOne(cartDTO.getProductId());        if (productInfo == null) {            throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);        }        //2、查出相应产品在数据库中的库存,进行比较        Integer result = productInfo.getProductStock()-cartDTO.getProductQuantity();        if(result<0){            throw new SellException(ResultEnum.PRODUCT_STOCK_ERROR);        }        //3、如果库存还有,就减库存        productInfo.setProductStock(result);        //4、存库        productInfoDao.save(productInfo);    }}

controller这一层:

@RestController@RequestMapping("/buyer/order")@Slf4jpublic class BuyerOrderController {    @Autowired    private OrderService orderService;    @RequestMapping("/create")    public ResultVO<Map<String,String>> create(@Valid OrderForm orderForm, BindingResult br){        //先进行数据的验证        if(br.hasErrors()){            log.error("【创建订单】参数不正确, orderForm={}", orderForm);            throw new SellException(ResultEnum.PARAM_ERROR);        }        //这里还要判断一下购物车是不是为空,就是items中有没有值        //这里的items是一个list,如果死List,就好处理了。。。        //并且创建订单所传入的对象是OrderDto,所以必须要转一下        OrderDto orderDto = OrderForm2OrderDTOConverter.convert(orderForm);        if(StringUtils.isEmpty(orderDto.getOrderDetailList())){            log.error("【创建订单】购物车不能为空");            throw new SellException(ResultEnum.CART_EMPTY);        }        //创建订单        OrderDto create = orderService.create(orderDto);        //返回orderId给前端        Map<String,String> map = new HashMap<>();        map.put("orderId",create.getOrderId());        return ResultVOUtil.success(map);    }}

对于转换的程序:

@Slf4jpublic class OrderForm2OrderDTOConverter {    public static OrderDto convert(OrderForm orderForm) {        Gson gson = new Gson();        OrderDto orderDto = new OrderDto();        orderDto.setBuyerName(orderForm.getName());        orderDto.setBuyerPhone(orderForm.getPhone());        orderDto.setBuyerAddress(orderForm.getAddress());        orderDto.setBuyerOpenid(orderForm.getOpenid());        List<OrderDetail> orderDetailList = new ArrayList<>();        try {            orderDetailList = gson.fromJson(orderForm.getItems(),                    new TypeToken<List<OrderDetail>>() {                    }.getType());        } catch (Exception e) {            log.error("【对象转换】错误, string={}", orderForm.getItems());            throw new SellException(ResultEnum.PARAM_ERROR);        }        orderDto.setOrderDetailList(orderDetailList);        return orderDto;    }}

主要是利用Gson将items这个类似于map的数据转为list。

postman进行测试:

localhost:8080/sell/buyer/order/create//以表单的形式提交,即x-www-form-urlencoded,点击右边的key-value-edit,将下面的复制进去:name:张三phone:18868822111address:慕课网总部openid:ew3euwhd7sjw9diwkqitems:[{productId:124,productQuantity: 1}]

返回:

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

3.2 查询某个订单

@Overridepublic OrderDto findOne(String orderid) {    OrderDto orderDto = new OrderDto();    OrderMaster orderMaster = orderMasterDao.findOne(orderid);    if(orderMaster == null){        throw new SellException(ResultEnum.ORDER_NOT_EXIST);    }    List<OrderDetail> orderDetailList = orderDetailDao.findByOrderId(orderid);    if(CollectionUtils.isEmpty(orderDetailList)){        throw new SellException(ResultEnum.ORDER_NOT_EXIST);    }    BeanUtils.copyProperties(orderMaster,orderDto);    orderDto.setOrderDetailList(orderDetailList);    return orderDto;}

3.3 订单列表

用户openid查询他的订单列表,不需要获取订单详情:

@Overridepublic Page<OrderDto> findListByOpenid(String openid, Pageable pageable) {    Page<OrderMaster> orderMasterPage = orderMasterDao.findByBuyerOpenid(openid,pageable);    List<OrderDto> orderDtoList = OrderMaster2OrderDTOConverter.convert(orderMasterPage.getContent());    return new PageImpl<OrderDto>(orderDtoList,pageable,orderMasterPage.getTotalElements());}

controller:

@RequestMapping("/list")public ResultVO<List<OrderDto>> list(@RequestParam("openid") String openid,                                     @RequestParam(value = "page", defaultValue = "0") Integer page,                                     @RequestParam(value = "size", defaultValue = "10") Integer size){    if (StringUtils.isEmpty(openid)){        log.error("【查询订单列表】openid为空");        throw new SellException(ResultEnum.PARAM_ERROR);    }    PageRequest pageRequest = new PageRequest(page,size);    Page<OrderDto> orderDtoPage = orderService.findListByOpenid(openid,pageRequest);    return ResultVOUtil.success(orderDtoPage.getContent());}

post请求:

localhost:8080/sell/buyer/order/list加上paranm:openid,page,size

返回:

{    "code": 0,    "msg": "成功",    "data": [        {            "orderId": "1512719526404570231",            "buyerName": "张三",            "buyerPhone": "18868822111",            "buyerAddress": "慕课网总部",            "buyerOpenid": "ew3euwhd7sjw9diwkq",            "orderAmount": 246,            "orderStatus": 0,            "payStatus": 0,            "createTime": 1512690726000,            "updateTime": 1512690726000,            "orderDetailList": null        },        {            "orderId": "1512719606250354875",            "buyerName": "张三",            "buyerPhone": "18868822111",            "buyerAddress": "慕课网总部",            "buyerOpenid": "ew3euwhd7sjw9diwkq",            "orderAmount": 9.3,            "orderStatus": 0,            "payStatus": 0,            "createTime": 1512690806000,            "updateTime": 1512690806000,            "orderDetailList": null        }    ]}

如果我们需要将null的不显示:

jackson:  default-property-inclusion: non_null

但是这个存在的问题是,如果我们想让空字符串以“”的形式展现:解决方法是在实体类中赋予初值。

3.4 取消订单

@Overridepublic OrderDto cancel(OrderDto orderDto) {    //1、判断订单的状态是不是新订单的状态,不是则抛出异常    if (!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {        log.error("【取消订单】订单状态不正确, orderId={}, orderStatus={}", orderDto.getOrderId(), orderDto.getOrderStatus());        throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);    }    //2、修改订单状态    OrderMaster orderMaster = new OrderMaster();    orderDto.setOrderStatus(OrderStatusEnum.CANCEL.getCode());    BeanUtils.copyProperties(orderDto,orderMaster);    orderMasterDao.save(orderMaster);    //3、返还库存    if (CollectionUtils.isEmpty(orderDto.getOrderDetailList())) {        log.error("【取消订单】订单中无商品详情, orderDTO={}", orderDto);        throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);    }    List<CartDTO> cartDTOList = orderDto.getOrderDetailList().stream()            .map(e -> new CartDTO(e.getProductId(),e.getProductQuantity()))            .collect(Collectors.toList());    productService.increaseStock(cartDTOList);    //4、TODO 如果已支付, 需要退款    return orderDto;}

3.5 支付订单

@Overridepublic OrderDto paid(OrderDto orderDto) {    if(!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){        log.error("【订单支付完成】订单状态不正确, orderId={}, orderStatus={}", orderDto.getOrderId(), orderDto.getOrderStatus());        throw new SellException(ResultEnum.ORDER_STATUS_ERROR);    }    if(!orderDto.getPayStatus().equals(PayStatusEnum.WAIT)){        log.error("【订单支付完成】订单支付状态不正确, orderDTO={}", orderDto);        throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);    }    OrderMaster orderMaster = new OrderMaster();    orderDto.setPayStatus(PayStatusEnum.SUCCESS.getCode());    BeanUtils.copyProperties(orderDto,orderMaster);    OrderMaster updateResult = orderMasterDao.save(orderMaster);    if (updateResult == null) {        log.error("【订单支付完成】更新失败, orderMaster={}", orderMaster);        throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);    }    return orderDto;}

3.6 完结订单

@Overridepublic OrderDto finish(OrderDto orderDto) {    if(!orderDto.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){        log.error("【取消订单】订单状态不正确, orderId={}, orderStatus={}", orderDto.getOrderId(), orderDto.getOrderStatus());        throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);    }    OrderMaster orderMaster = new OrderMaster();    orderDto.setOrderStatus(OrderStatusEnum.FINISHED.getCode());    BeanUtils.copyProperties(orderDto,orderMaster);    OrderMaster updateResult = orderMasterDao.save(orderMaster);    if (updateResult == null) {        log.error("【完结订单】更新失败, orderMaster={}", orderMaster);        throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);    }    return orderDto;    //TODO 发送模板消息}

4、controller层:

//订单详情@GetMapping("/detail")public ResultVO detail(@RequestParam("openid") String openid,                       @RequestParam("orderid") String orderid) {    OrderDto orderDTO = buyerService.findOrderOne(openid, orderid);    return ResultVOUtil.success(orderDTO);}//取消订单@PostMapping("/cancel")public ResultVO cancel(@RequestParam("openid") String openid,                       @RequestParam("orderid") String orderid) {    buyerService.cancelOrder(openid, orderid);    return ResultVOUtil.success();}

这里将订单详情和取消订单集成到BuyerServiceImpl中:

@Service@Slf4jpublic class BuyerServiceImpl implements BuyerService{    @Autowired    private OrderService orderService;    @Override    public OrderDto findOrderOne(String openid, String orderId) {        return checkOrderOwner(openid,orderId);    }    @Override    public OrderDto cancelOrder(String openid, String orderId) {        OrderDto orderDto = checkOrderOwner(openid,orderId);        if(orderDto==null){            log.error("【取消订单】查不到改订单, orderId={}", orderId);            throw new SellException(ResultEnum.ORDER_NOT_EXIST);        }        return orderService.cancel(orderDto);    }    private OrderDto checkOrderOwner(String openid, String orderId){        OrderDto orderDto = orderService.findOne(orderId);        if (orderDto == null) {            return null;        }        if(!orderDto.getBuyerOpenid().equalsIgnoreCase(openid)){            log.error("【查询订单】订单的openid不一致. openid={}, orderDTO={}", openid, orderDto);            throw new SellException(ResultEnum.ORDER_OWNER_ERROR);        }        return orderDto;    }}
原创粉丝点击