首页 > 其他分享 >订单处理-cnblog

订单处理-cnblog

时间:2023-02-04 16:33:35浏览次数:43  
标签:orderDetail item 处理 addressBook 用户 orders 订单 下单 cnblog

4.5 代码开发

在OrderController中创建submit方法,处理用户下单的逻辑 :

/**
 * 用户下单
 * @param orders
 * @return
 */
@PostMapping("/submit")
public R<String> submit(@RequestBody Orders orders){
    log.info("订单数据:{}",orders);
    orderService.submit(orders);
    return R.success("下单成功");
}

由于下单的逻辑相对复杂,我们可以在OrderService中定义submit方法,来处理下单的具体逻辑:

/**
* 用户下单
* @param orders
*/
public void submit(Orders orders);

然后在OrderServiceImpl中完成下单功能的具体实现,下单功能的具体逻辑如下:

A. 获得当前用户id, 查询当前用户的购物车数据

B. 根据当前登录用户id, 查询用户数据

C. 根据地址ID, 查询地址数据

D. 组装订单明细数据, 批量保存订单明细

E. 组装订单数据, 批量保存订单数据

F. 删除当前用户的购物车列表数据

具体代码实现如下:

@Autowired
private ShoppingCartService shoppingCartService;

@Autowired
private UserService userService;

@Autowired
private AddressBookService addressBookService;

@Autowired
private OrderDetailService orderDetailService;

/**
* 用户下单
* @param orders
*/
@Transactional
public void submit(Orders orders) {
    //获得当前用户id
    Long userId = BaseContext.getCurrentId();

    //查询当前用户的购物车数据
    LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(ShoppingCart::getUserId,userId);
    List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);

    if(shoppingCarts == null || shoppingCarts.size() == 0){
    	throw new CustomException("购物车为空,不能下单");
    }

    //查询用户数据
    User user = userService.getById(userId);

    //查询地址数据
    Long addressBookId = orders.getAddressBookId();
    AddressBook addressBook = addressBookService.getById(addressBookId);
    if(addressBook == null){
    	throw new CustomException("用户地址信息有误,不能下单");
    }

    long orderId = IdWorker.getId();//订单号

    AtomicInteger amount = new AtomicInteger(0);

    //组装订单明细信息
    List<OrderDetail> orderDetails = shoppingCarts.stream().map((item) -> {
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        orderDetail.setNumber(item.getNumber());
        orderDetail.setDishFlavor(item.getDishFlavor());
        orderDetail.setDishId(item.getDishId());
        orderDetail.setSetmealId(item.getSetmealId());
        orderDetail.setName(item.getName());
        orderDetail.setImage(item.getImage());
        orderDetail.setAmount(item.getAmount());
        amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());
        return orderDetail;
    }).collect(Collectors.toList());

    //组装订单数据
    orders.setId(orderId);
    orders.setOrderTime(LocalDateTime.now());
    orders.setCheckoutTime(LocalDateTime.now());
    orders.setStatus(2);
    orders.setAmount(new BigDecimal(amount.get()));//总金额
    orders.setUserId(userId);
    orders.setNumber(String.valueOf(orderId));
    orders.setUserName(user.getName());
    orders.setConsignee(addressBook.getConsignee());
    orders.setPhone(addressBook.getPhone());
    orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
        + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
        + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
        + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
    //向订单表插入数据,一条数据
    this.save(orders);

    //向订单明细表插入数据,多条数据
    orderDetailService.saveBatch(orderDetails);

    //清空购物车数据
    shoppingCartService.remove(wrapper);
}

备注:

​ 上述逻辑处理中,计算购物车商品的总金额时,为保证我们每一次执行的累加计算是一个原子操作,我们这里用到了JDK中提供的一个原子类 AtomicInteger

标签:orderDetail,item,处理,addressBook,用户,orders,订单,下单,cnblog
From: https://www.cnblogs.com/lingxin1123/p/17091840.html

相关文章

  • 第13章 远程处理:一对一及一对多
    第13章远程处理:一对一及一对多13.1PowerShell远程处理的原理在一定程度上讲,PowerShell的远程处理类似于Telnet或者其他一些老旧的远程处理技术。当键入命令时,它会......
  • 第16章 同时处理多个对象
    第16章同时处理多个对象PowerShell存在的主要意义在于自动化管理,这通常意味着你将会在多个目标上同时执行任务。你或许希望重启多台计算机,重新配置多个服务,修改多个......
  • vue计算属性的完整写法-cnblog
    简单写法,给计算属性赋值报错解决方案:提供set方法实例(全选-->反选,反选->全选)<template><div><span>全选:</span><!--4.v-model关联全选-选中状态......
  • vue作用域插槽-cnblog
    使用场景:父组件需要使用到子组件的data时例子父组件有list数组,传递给子组件,子组件将数组中的属性全部显示出来,但是用什么标签显示这些属性不确定(使用插槽)父组件传......
  • vue侦听器深度侦听-cnblog
    简单类型不需要加上引号如对象user.name(注意加上引号)watch:{ "obj.name":{ ...}}侦听器的应用(存入本地存储localStorage)也可以在组件销毁时存入本......
  • async和await-cnblog
    在之前对promise对象的处理使用Promise原型函数then,catch解决回调地狱的问题,但存在冗余代码.then().then().then()asyncawaites8(esma2017)引入awaitPromis......
  • lightweight处理关键点。
    ConvertKeypoints()交换关键点顺序,剩下其他代码并未交换顺序def_convert(self,keypoints,w,h):#Nose,Neck,Rhand,Lhand,Rleg,Lleg,Eyes,Ears......
  • JavaScript高级第01天笔记-cnblog
    JavaScript高级第01天笔记1.面向过程与面向对象1.1面向过程面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用......
  • JavaScript高级第02天笔记-cnblog
    JavaScript高级第02天笔记1.构造函数和原型1.1对象的三种创建方式--复习字面量方式varobj={};new关键字varobj=newObject();构造函数方式function......
  • JavaScript高级第03天笔记-cnblog
    JavaScript高级第03天笔记1.函数的定义和调用1.1函数的定义方式方式1函数声明方式function关键字(命名函数)functionfn(){}方式2函数表达式(匿名函数)var......