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; }}
阅读全文
0 0
- 4、订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 订单
- 客户订单 生产订单
- 进销存设计与分析_采购订单(4)
- 进销存设计与分析_采购订单(4)收藏
- .Net Pet Shop 4 初探之五:订单管理模块
- 在oracle ERP中将采购订单类型分为4类
- nlp简单深度模型的代码套路
- 2、商品的dao和service
- Java学习(二) Java基础知识
- 3、商品和类目的controller
- java EE
- 4、订单
- 第十四周java作业
- 水深火热
- 5、部署在本机环境
- Oracle Database 11g Express Edition is already configured
- PyQt5学习
- Grpc使用实践总结
- 1003. 我要通过!(20)
- 6、卖家订单部分