新峰商城之订单(二):订单生成

        在订单确认页面处理完毕后,此时用户单击“提交订单”按钮,商城系统就对应生成一笔订单数据并保存在数据库中,此即订单生成功能。

        在单击“提交订单”按钮后,后端会进行一系列操作,包括数据查询、数据判断、数据整合等,订单生成流程图如下所示:

一、发起订单生成请求

        在订单确认页面order-settle.html中,编写“提交订单”按钮单击事件,代码如下所示:

$('#saveOrder').click(function () {
        var userAddress = $(".user_address_label").html();
        if (userAddress == '' || userAddress == '无') {
            Swal.fire({
                text: "请填写收货信息",
                icon: "error",iconColor:"#f05b72",
            });
            return;
        }
        if (userAddress.trim().length < 10) {
            Swal.fire({
                text: "请输入正确的收货信息",
                icon: "error",iconColor:"#f05b72",
            });
            return;
        }
        window.location.href = '../saveOrder';
    });

        前端主要验证用户输入的信息是否正确,如果验证通过,则向saveOrder请求地址发起订单生成请求。

二、订单生成请求处理

        首先在controller包中新建OrderController类用于处理订单模块的相关请求,然后新增saveOrder()方法用于订单生成的请求,代码如下所示:

@GetMapping("/saveOrder")
public String saveOrder(HttpSession httpSession) {
        NewBeeMallUserVO user = (NewBeeMallUserVO) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        List<NewBeeMallShoppingCartItemVO> myShoppingCartItems = newBeeMallShoppingCartService.getMyShoppingCartItems(user.getUserId());
        if (!StringUtils.hasText(user.getAddress().trim())) {
            //无收货地址
            NewBeeMallException.fail(ServiceResultEnum.NULL_ADDRESS_ERROR.getResult());
        }
        if (CollectionUtils.isEmpty(myShoppingCartItems)) {
            //购物车中无数据则跳转至错误页
            NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        }
        //保存订单并返回订单号
        String saveOrderResult = newBeeMallOrderService.saveOrder(user, myShoppingCartItems);
        //跳转到订单详情页
        return "redirect:/orders/" + saveOrderResult;
    }

        此方法处理的映射地址为/saveOrder,请求方法为GET,过程如下所示:

(1)验证收货地址信息

(2)验证购物车中是否有数据

(3)将购物项数据和用户信息作为参数传递给saveOrder()方法

(4)如果订单生成成功,则返回订单号,跳转至订单详情页

    

三、订单生成逻辑的实现

        在service包中新建订单模块的业务实现类,并实现订单生成的业务逻辑,代码如下所示:

@Override
@Transactional
public String saveOrder(NewBeeMallUserVO user, List<NewBeeMallShoppingCartItemVO> myShoppingCartItems) {
        List<Long> itemIdList = myShoppingCartItems.stream().map(NewBeeMallShoppingCartItemVO::getCartItemId).collect(Collectors.toList());
        List<Long> goodsIds = myShoppingCartItems.stream().map(NewBeeMallShoppingCartItemVO::getGoodsId).collect(Collectors.toList());
        List<NewBeeMallGoods> newBeeMallGoods = newBeeMallGoodsMapper.selectByPrimaryKeys(goodsIds);
        //检查是否包含已下架商品
        List<NewBeeMallGoods> goodsListNotSelling = newBeeMallGoods.stream()
                .filter(newBeeMallGoodsTemp -> newBeeMallGoodsTemp.getGoodsSellStatus() != Constants.SELL_STATUS_UP)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(goodsListNotSelling)) {
            //goodsListNotSelling 对象非空则表示有下架商品
            NewBeeMallException.fail(goodsListNotSelling.get(0).getGoodsName() + "已下架,无法生成订单");
        }
        Map<Long, NewBeeMallGoods> newBeeMallGoodsMap = newBeeMallGoods.stream().collect(Collectors.toMap(NewBeeMallGoods::getGoodsId, Function.identity(), (entity1, entity2) -> entity1));
        //判断商品库存
        for (NewBeeMallShoppingCartItemVO shoppingCartItemVO : myShoppingCartItems) {
            //查出的商品中不存在购物车中的这条关联商品数据,直接返回错误提醒
            if (!newBeeMallGoodsMap.containsKey(shoppingCartItemVO.getGoodsId())) {
                NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
            }
            //存在数量大于库存的情况,直接返回错误提醒
            if (shoppingCartItemVO.getGoodsCount() > newBeeMallGoodsMap.get(shoppingCartItemVO.getGoodsId()).getStockNum()) {
                NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
            }
        }
        //删除购物项
        if (!CollectionUtils.isEmpty(itemIdList) && !CollectionUtils.isEmpty(goodsIds) && !CollectionUtils.isEmpty(newBeeMallGoods)) {
            if (newBeeMallShoppingCartItemMapper.deleteBatch(itemIdList) > 0) {
                List<StockNumDTO> stockNumDTOS = BeanUtil.copyList(myShoppingCartItems, StockNumDTO.class);
                int updateStockNumResult = newBeeMallGoodsMapper.updateStockNum(stockNumDTOS);
                if (updateStockNumResult < 1) {
                    NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
                }
                //生成订单号
                String orderNo = NumberUtil.genOrderNo();
                int priceTotal = 0;
                //保存订单
                NewBeeMallOrder newBeeMallOrder = new NewBeeMallOrder();
                newBeeMallOrder.setOrderNo(orderNo);
                newBeeMallOrder.setUserId(user.getUserId());
                newBeeMallOrder.setUserAddress(user.getAddress());
                //总价
                for (NewBeeMallShoppingCartItemVO newBeeMallShoppingCartItemVO : myShoppingCartItems) {
                    priceTotal += newBeeMallShoppingCartItemVO.getGoodsCount() * newBeeMallShoppingCartItemVO.getSellingPrice();
                }
                if (priceTotal < 1) {
                    NewBeeMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                newBeeMallOrder.setTotalPrice(priceTotal);
                //订单body字段,用来作为生成支付单描述信息,暂时未接入第三方支付接口,故该字段暂时设为空字符串
                String extraInfo = "";
                newBeeMallOrder.setExtraInfo(extraInfo);
                //生成订单项并保存订单项纪录
                if (newBeeMallOrderMapper.insertSelective(newBeeMallOrder) > 0) {
                    //生成所有的订单项快照,并保存至数据库
                    List<NewBeeMallOrderItem> newBeeMallOrderItems = new ArrayList<>();
                    for (NewBeeMallShoppingCartItemVO newBeeMallShoppingCartItemVO : myShoppingCartItems) {
                        NewBeeMallOrderItem newBeeMallOrderItem = new NewBeeMallOrderItem();
                        //使用BeanUtil工具类将newBeeMallShoppingCartItemVO中的属性复制到newBeeMallOrderItem对象中
                        BeanUtil.copyProperties(newBeeMallShoppingCartItemVO, newBeeMallOrderItem);
                        //NewBeeMallOrderMapper文件insert()方法中使用了useGeneratedKeys因此orderId可以获取到
                        newBeeMallOrderItem.setOrderId(newBeeMallOrder.getOrderId());
                        newBeeMallOrderItems.add(newBeeMallOrderItem);
                    }
                    //保存至数据库
                    if (newBeeMallOrderItemMapper.insertBatch(newBeeMallOrderItems) > 0) {
                        //所有操作成功后,将订单号返回,以供Controller方法跳转到订单详情
                        return orderNo;
                    }
                    NewBeeMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                NewBeeMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
            }
            NewBeeMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
        }
        NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
    }

        订单生成方法先验证,再进行订单数据封装,最后将订单数据和订单项数据保存到数据库中,其     详细过程如下所示:

        (1)检查结算商品中是否包含已下架商品

        (2)判断商品数据和商品库存

        (3)对象的非空判断

        (4)生成订单后,删除相应的购物项数据

        (5)更新商品库存记录

        (6)判断订单价格

        (7)生成订单号并封装成对象,保存订单记录至数据库

        (8)封装订单项并保存至数据库

        (9)返回新订单的订单号

        在此方法中添加@Transactional注解,若执行过程中出现异常,则回滚事务。

     

抱歉,我无法直接为您生成具体的代码片段,因为黑马商城的后端代码会非常依赖于您的项目架构、使用的编程语言和技术栈(如Spring Boot、Django还是Node.js等)。通常,提交订单的后端流程包括验证用户信息、选择商品规格、计算总价、检查库存、创建订单记录并保存到数据库等步骤。 下面是一个简化的Python(Flask框架)的例子,展示了一个基本的订单提交API接口: ```python from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'your_database_url' db = SQLAlchemy(app) class Product(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) price = db.Column(db.Float) class Order(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) products = db.relationship('Product', backref='orders') @app.route('/submit_order', methods=['POST']) def submit_order(): data = request.get_json() # 验证数据 if not data or 'user_id' not in data or 'products' not in data: return jsonify({'error': 'Invalid data'}), 400 # 检查用户是否存在 user = User.query.get(data['user_id']) if not user: return jsonify({'error': 'User not found'}), 404 # 计算总价 total_price = sum(p['price'] for p in data['products']) # 创建订单并保存 new_order = Order(user=user, total_price=total_price) db.session.add(new_order) db.session.commit() return jsonify({'message': 'Order submitted successfully', 'order_id': new_order.id}), 201 # ...其他模型和路由定义... ``` 这只是一个基本示例,实际应用中需要处理更多的边缘情况,并可能涉及到事务处理、库存管理、支付接口集成等复杂功能。如果您需要更详细的帮助,建议咨询专业的开发者或者查阅相关技术文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值