• Tmall商城订单管理模块分析


    商城订单管理

    商品显示页

    从商品的显示页中加入购物车或者下单。

    跳转页面的请求地址(Get方式请求)

    http://localhost:8080/tmall/product/{pid}

    Request URL: http://localhost:8080/tmall/product/13
    Request Method: GET
    
    • 1
    • 2

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovoXg0Ek-1660310355881)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811141404430.png)]

    涉及到的控制器ForeProductDetailsController

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6cAFK7o-1660310355883)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811142053341.png)]

    //转到前台天猫-产品详情页
        @RequestMapping(value = "product/{pid}", method = RequestMethod.GET)
        public String goToPage(HttpSession session, Map<String, Object> map,
                               @PathVariable("pid") String pid /*产品ID*/) {
            logger.info("检查用户是否登录");
            Object userId = checkUser(session);
            if (userId != null) {
                logger.info("获取用户信息");
                User user = userService.get(Integer.parseInt(userId.toString()));
                map.put("user", user);
            }
            logger.info("获取产品ID");
            Integer product_id = Integer.parseInt(pid);
            logger.info("获取产品信息");
            Product product = productService.get(product_id);
            if (product == null || product.getProduct_isEnabled() == 1) {
                return "redirect:/404";
            }
            logger.info("获取产品子信息-分类信息");
            product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
            logger.info("获取产品子信息-预览图片信息");
            List<ProductImage> singleProductImageList = productImageService.getList(product_id, (byte) 0, null);
            product.setSingleProductImageList(singleProductImageList);
            logger.info("获取产品子信息-详情图片信息");
            List<ProductImage> detailsProductImageList = productImageService.getList(product_id, (byte) 1, null);
            product.setDetailProductImageList(detailsProductImageList);
            logger.info("获取产品子信息-产品属性值信息");
            List<PropertyValue> propertyValueList = propertyValueService.getList(new PropertyValue().setPropertyValue_product(product), null);
            logger.info("获取产品子信息-分类信息对应的属性列表");
            List<Property> propertyList = propertyService.getList(new Property().setProperty_category(product.getProduct_category()), null);
            logger.info("属性列表和属性值列表合并");
            for (Property property : propertyList) {
                for (PropertyValue propertyValue : propertyValueList) {
                    if (property.getProperty_id().equals(propertyValue.getPropertyValue_property().getProperty_id())) {
                        List<PropertyValue> property_value_item = new ArrayList<>(1);
                        property_value_item.add(propertyValue);
                        property.setPropertyValueList(property_value_item);
                        break;
                    }
                }
            }
            logger.info("获取产品子信息-产品评论信息");
            product.setReviewList(reviewService.getListByProductId(product_id, null));
            if (product.getReviewList() != null) {
                for (Review review : product.getReviewList()) {
                    review.setReview_user(userService.get(review.getReview_user().getUser_id()));
                }
            }
    
            logger.info("获取猜你喜欢列表");
            Integer category_id = product.getProduct_category().getCategory_id();
            Integer total = productService.getTotal(new Product().setProduct_category(new Category().setCategory_id(category_id)), new Byte[]{0, 2});
            logger.info("分类ID为{}的产品总数为{}条", category_id, total);
            //生成随机数
            int i = new Random().nextInt(total);
            if (i + 2 >= total) {
                i = total - 3;
            }
            if (i < 0) {
                i = 0;
            }
            List<Product> loveProductList = productService.getList(new Product().setProduct_category(
                    new Category().setCategory_id(category_id)),
                    new Byte[]{0, 2},
                    null,
                    new PageUtil().setCount(3).setPageStart(i)
            );
            if (loveProductList != null) {
                logger.info("获取产品列表的相应的一张预览图片");
                for (Product loveProduct : loveProductList) {
                    loveProduct.setSingleProductImageList(productImageService.getList(loveProduct.getProduct_id(), (byte) 0, new PageUtil(0, 1)));
                }
            }
            logger.info("获取分类列表");
            List<Category> categoryList = categoryService.getList(null, new PageUtil(0, 3));
    
            map.put("loveProductList", loveProductList);
            map.put("categoryList", categoryList);
            map.put("propertyList", propertyList);
            map.put("product", product);
            map.put("guessNumber", i);
            map.put("pageUtil", new PageUtil(0, 10).setTotal(product.getProduct_review_count()));
            logger.info("转到前台-产品详情页");
            return "fore/productDetailsPage";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    根据最后返回的地址,确定对应的页面位置:

    fore/productDetailsPage

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-snL3IfZ5-1660310355885)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811142345032.png)]

    加入购物车的代码流程

    <form method="get" class="context_buy_form">
          <input class="context_buyNow" type="submit" value="立即购买"/>
    form>
    
    • 1
    • 2
    • 3

    JS绑定事件

    点击添加购物车按钮之后向后台发送请求。

    涉及部分

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQhbVEXM-1660310355885)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811143348295.png)]

    数量
    库存1000件
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    知识点一:isNaN函数

    定义和用法

    isNaN() 函数用于检查其参数是否是非数字值。

    语法
    isNaN(x)
    
    • 1
    参数描述
    x必需。要检测的值。
    返回值

    如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false。

    说明

    isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。

    如果把 NaN 与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。

    提示和注释

    提示:isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字。当然也可以用 isNaN() 函数来检测算数错误,比如用 0 作除数的情况。

    实例

    检查数字是否非法:

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    false
    false
    false
    false
    true
    true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建购物车向后端发送请求

    $.trim(str)的作用是去掉字符串首尾空格

    $.trim(str)

    返回:string;

    在前端的过程中通过jquery进行校验,如果时非法数字重新进行刷新,正常数字会发送请求参数。

    发送请求的方式为post方式,

    发送的地址为:/orderItem/create/{产品id}

    携带的参数:product_number:购买的数量

     $(".context_buyCar_form").submit(function () {
                            if ('${sessionScope.userId}' === "") {
                                $(".loginModel").show();
                                $(".loginDiv").show();
                                return false;
                            }
                            var number = isNaN($.trim($(".context_buymember").val()));
                            if (number) {
                                location.reload();
                            } else {
                                $.ajax({
                                    url: 							"${pageContext.request.contextPath}/orderItem/create/${requestScope.product.product_id}?product_number=" + $.trim($(".context_buymember").val()),
                                    type: "POST",
                                    data: {"product_number": number},
                                    dataType: "json",
                                    success: function (data) {
                                        if (data.success) {
                                            $(".msg").stop(true, true).animate({
                                                opacity: 1
                                            }, 550, function () {
                                                $(".msg").animate({
                                                    opacity: 0
                                                }, 1500);
                                            });
                                        } else {
                                            if (data.url != null) {
                                                location.href = "/tmall" + data.url;  //里面的data.url为后端返回的
                                            } else {
                                                alert("加入购物车失败,请稍后再试!");
                                            }
                                        }
                                    },
                                    beforeSend: function () {
    
                                    },
                                    error: function () {
                                        alert("加入购物车失败,请稍后再试!");
                                    }
                                });
                                return false;
                            }
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在请求后端的参数成功之后。弹出添加购物车成功的弹窗

    用于创建自定义动画的函数。
    返回值:jQuery animate(params, [duration], [easing], [callback])

    如果使用的是“hide”、“show”或“toggle”这样的字符串值,则会为该属性调用默认的动画形式。paramsOptions一组包

    含作为动画属性和终值的样式属性和及其值的集合

    完成成功之后的操作对应着,创建自定义提示的交互过程

    后端的ForeOrderController控制器接收请求

    涉及到的控制器:ForeOrderController(核心的订单处理控制器)

    核心控制器中包含的方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pds1fNSi-1660310355887)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811145943234.png)]

    //创建订单项-购物车-ajax
    @ResponseBody
    @RequestMapping(value = "orderItem/create/{product_id}", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
    public String createOrderItem(@PathVariable("product_id") Integer product_id,
                                  @RequestParam(required = false, defaultValue = "1") Short product_number,
                                  HttpSession session,
                                  HttpServletRequest request) {
        JSONObject object = new JSONObject();
        logger.info("检查用户是否登录");
        Object userId = checkUser(session);
        if (userId == null) {
            object.put("url", "/login");
            object.put("success", false);
            return object.toJSONString();
        }
    
        logger.info("通过产品ID获取产品信息:{}", product_id);
        Product product = productService.get(product_id);
        if (product == null) {
            object.put("url", "/login");
            object.put("success", false);
            return object.toJSONString();
        }
    
        ProductOrderItem productOrderItem = new ProductOrderItem();
        logger.info("检查用户的购物车项");
        List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
        for (ProductOrderItem orderItem : orderItemList) {
            if (orderItem.getProductOrderItem_product().getProduct_id().equals(product_id)) {
                logger.info("找到已有的产品,进行数量追加");
                int number = orderItem.getProductOrderItem_number();
                number += 1;
                productOrderItem.setProductOrderItem_id(orderItem.getProductOrderItem_id());
                productOrderItem.setProductOrderItem_number((short) number);
                productOrderItem.setProductOrderItem_price(number * product.getProduct_sale_price());
                boolean yn = productOrderItemService.update(productOrderItem);
                if (yn) {
                    object.put("success", true);
                } else {
                    object.put("success", false);
                }
                return object.toJSONString();
            }
        }
        logger.info("封装订单项对象");
        productOrderItem.setProductOrderItem_product(product);
        productOrderItem.setProductOrderItem_number(product_number);
        productOrderItem.setProductOrderItem_price(product.getProduct_sale_price() * product_number);
        productOrderItem.setProductOrderItem_user(new User().setUser_id(Integer.valueOf(userId.toString())));
        boolean yn = productOrderItemService.add(productOrderItem);
        if (yn) {
            object.put("success", true);
        } else {
            object.put("success", false);
        }
        return object.toJSONString();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    在执行核心的方法之前首先检查,登录状态:调用Basecontroller

    //检查用户是否登录
    protected Object checkUser(HttpSession session){
        Object o = session.getAttribute("userId");
        if(o==null){
            logger.info("用户未登录");
            return null;
        }
        logger.info("用户已登录,用户ID:{}", o);
        return o;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    知识点二:@PathVariable 映射 URL 绑定的[占位符]

    • 带占位符的 URLSpring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
    • 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。

    知识点三:JSONObject 对象

    用法实例

    import org.json.JSONObject;
    
    public class JSONObjectSample {
    public static void main(String[] args) {
        createJson();
    }
     
    private static void createJson() {
        JSONObject obj = new JSONObject();
        obj.put("name", "John");
        obj.put("sex", "male");
        obj.put("age", 22);
        obj.put("is_student", true);
        obj.put("hobbies", new String[] {"hiking", "swimming"});
        //调用toString()方法可直接将其内容打印出来
        System.out.println(obj.toString());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    执行结果

    {“hobbies”:[“hiking”,“swimming”],“sex”:“male”,“name”:“John”,“is_student”:true,“age”:22}

    断点调试,查看返回的商品信息

    根据id获取需要添加到购物车中的产品信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LnX7y0X9-1660310355888)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811151359660.png)]

    返回商品信息之后在创建ProductOrderItem(产品订单项)

    private Integer productOrder_id/*订单ID*/;
    private String productOrder_code/*订单流水号*/;
    private Address productOrder_address/*订单地址*/;
    private String productOrder_detail_address/*订单详细地址*/;
    private String productOrder_post/*订单邮政编码*/;
    private String productOrder_receiver/*订单收货人名称*/;
    private String productOrder_mobile/*订单收货人号码*/;
    private Date productOrder_pay_date/*订单支付日期*/;
    private Date productOrder_delivery_date/*订单发货日期*/;
    private Date productOrder_confirm_date/*订单确认日期*/;
    private Byte productOrder_status/*订单状态*/;
    private User productOrder_user/*订单对应用户*/;
    private List<ProductOrderItem> productOrderItemList/*订单项集合*/;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Integer.valueOf()和Integer.valueOf()这两个方法都是Integer的静态方法,都可以传入一个只包含整数的字符串类型,将其转换为整数。

    List orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()),
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFbXzxot-1660310355889)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811152410217.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6UqtD4i8-1660310355890)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811152744678.png)]

    执行for循环语句,找到购物车中的原有项数目加number,没有则会跳出循环,来创建新订单

    for (ProductOrderItem orderItem : orderItemList) {
                if (orderItem.getProductOrderItem_product().getProduct_id().equals(product_id)) {
                    logger.info("找到已有的产品,进行数量追加");
                    int number = orderItem.getProductOrderItem_number();
                    number += 1;
                    productOrderItem.setProductOrderItem_id(orderItem.getProductOrderItem_id());
                    productOrderItem.setProductOrderItem_number((short) number);
                    productOrderItem.setProductOrderItem_price(number * product.getProduct_sale_price());
                    boolean yn = productOrderItemService.update(productOrderItem);
                    if (yn) {
                        object.put("success", true);
                    } else {
                        object.put("success", false);
                    }
                    return object.toJSONString();
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RFEy8PhP-1660310355890)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811153702936.png)]

    如果匹配成功则会在for循环中修改订单的信息完成对应的修改操作。

    调用update语句修改订单项,之后完成数据库更新

    boolean yn = productOrderItemService.update(productOrderItem);
    
    • 1

    到这位置添加购物车订单的流程执行完毕

    购物车显示页

    请求地址:

    Request URL: http://localhost:8080/tmall/cart

    请求方式:get方式

    请求方法说明://转到前台天猫-购物车页

    返回地址:fore/productBuyCarPage(前端的购物车显示页面)

    //转到前台天猫-购物车页
        @RequestMapping(value = "cart", method = RequestMethod.GET)
        public String goToCartPage(Map<String, Object> map, HttpSession session) {
            logger.info("检查用户是否登录");
            Object userId = checkUser(session);
            User user;
            if (userId != null) {
                logger.info("获取用户信息");
                user = userService.get(Integer.parseInt(userId.toString()));
                map.put("user", user);
            } else {
                return "redirect:/login";
            }
            logger.info("获取用户购物车信息");
            List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
            Integer orderItemTotal = 0;
            if (orderItemList.size() > 0) {
                logger.info("获取用户购物车的商品总数");
                orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));
                logger.info("获取用户购物车内的商品信息");
                for (ProductOrderItem orderItem : orderItemList) {
                    Integer product_id = orderItem.getProductOrderItem_product().getProduct_id();
                    Product product = productService.get(product_id);
                    product.setSingleProductImageList(productImageService.getList(product_id, (byte) 0, null));
                    product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
                    orderItem.setProductOrderItem_product(product);
                }
            }
            map.put("orderItemList", orderItemList);
            map.put("orderItemTotal", orderItemTotal);
    
            logger.info("转到前台天猫-购物车页");
            return "fore/productBuyCarPage";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    ForeOrderController处理请求完成页面跳转

    方法名goToCartPage()

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tYGsEZI-1660310355891)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811155541174.png)]

    断点调试:走获取购物车信息的流程

    之前要先获取用户的信息(从session中的userid中获取信息->查出user的信息)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gfJTMI5P-1660310355892)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811155958480.png)]

    通过调用业务逻辑层(和之前的复用)

    List orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2jW28ShK-1660310355892)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811160309917.png)]

    最后获取购物车中的商品总数和对应的信息,完成操作

    orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));

    if (orderItemList.size() > 0) {
                logger.info("获取用户购物车的商品总数");
                orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));
                logger.info("获取用户购物车内的商品信息");
                for (ProductOrderItem orderItem : orderItemList) {
                    Integer product_id = orderItem.getProductOrderItem_product().getProduct_id();
                    Product product = productService.get(product_id); //获取一条产品
                    product.setSingleProductImageList(productImageService.getList(product_id, (byte) 0, null));//获取对应的图片
                    product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
                    orderItem.setProductOrderItem_product(product);
                }
            }
            map.put("orderItemList", orderItemList);
            map.put("orderItemTotal", orderItemTotal);
    
            logger.info("转到前台天猫-购物车页");
            return "fore/productBuyCarPage";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    //设置订单对应的产品

    private Product productOrderItem_product/*订单项对应产品*/;
    
    • 1

    最后通过map集合进行封装,将携带的数据返回到前台的jsp页面中

    map.put("orderItemList", orderItemList);
            map.put("orderItemTotal", orderItemTotal);
    
            logger.info("转到前台天猫-购物车页");
            return "fore/productBuyCarPage";
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在前台的页面进行map集合数据的遍历和渲染

    ${requestScope.orderItemTotal}

    已选商品(不含运费)  0.00 结 算
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    数据表格渲染(c:foreach标签)

    
        
            店铺:贤趣${orderItem.productOrderItem_product.product_category.category_name}旗舰店
            
        
        
            
            ${orderItem.productOrderItem_product.product_name}
            
            ¥${orderItem.productOrderItem_price/orderItem.productOrderItem_number}
            
            
                
            
            
                ¥${orderItem.productOrderItem_price}
            
            删除
            
                
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    购物车删除操作

    请求路径:http://localhost:8080/tmall/orderItem/909

    请求方式:delete方式

    携带参数:订单编号

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rLJgC2em-1660310355893)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220811170949637.png)]

    ForeOrderController控制器处理删除操作

    //删除订单项-购物车-ajax
        @ResponseBody
        @RequestMapping(value = "orderItem/{orderItem_id}", method = RequestMethod.DELETE, produces = "application/json;charset=utf-8")
        public String deleteOrderItem(@PathVariable("orderItem_id") Integer orderItem_id,
                                      HttpSession session,
                                      HttpServletRequest request) {
            JSONObject object = new JSONObject();
            logger.info("检查用户是否登录");
            Object userId = checkUser(session);
            if (userId == null) {
                object.put("url", "/login");
                object.put("success", false);
                return object.toJSONString();
            }
            logger.info("检查用户的购物车项");
            List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
            boolean isMine = false;
            for (ProductOrderItem orderItem : orderItemList) {
                logger.info("找到匹配的购物车项");
                if (orderItem.getProductOrderItem_id().equals(orderItem_id)) {
                    isMine = true;
                    break;
                }
            }
            if (isMine) {
                logger.info("删除订单项信息");
                boolean yn = productOrderItemService.deleteList(new Integer[]{orderItem_id});
                if (yn) {
                    object.put("success", true);
                } else {
                    object.put("success", false);
                }
            } else {
                object.put("success", false);
            }
            return object.toJSONString();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    注意:批量删除操作还没有实现

    购物车单个结算的操作

    单个结算的购物地址:http://localhost:8080/tmall/orderItem

    请求方式Put

    说明:在提交订单之前完成先更新购物车中的信息

    知识点四:JSONObject、MAP、对象、字符串互相转换

    实体类(User类)、JSON对象、json字符串

    JSONObject jsonObject = JSON.parseObject(user); // 转换为json对象 JSONObject jso = (JSONObject) JSON.toJSON(user); // 转换为json对象`

    String personStr = JSONObject.toJSONString(user); // 转换为json字符串

    String str = JSON.toJSONString(user); // 转换为json字符串`

    User user = jsonObject.toJavaObject(User.class); // json对象转换为实体类 JSON.parseObject(“{“band”:“XX”,“price”:“888”}”, User.class) //String类型json转换为实体类`
    2)、List、数组、Map与json代码转换

    JSONObject itemJSONObj = JSONObject.parseObject(JSON.toJSONString(itemMap)); //将Map类型的itemInfo转换成json,再经JSONObject转换实现。
    JSONObject itemJSONObj = JSONObject.parseObject(JSON.toJSONString(list)); // list转换
    JSONArray jsonArray1 = JSONArray.parseObject(JSON.toJSONString(array)); // 数组转换为JSONObject

    搞清楚JSONObject的操作步骤

    JSONObject orderItemString = JSON.parseObject(orderItemMap);
    Set<String> orderItemIDSet = orderItemString.keySet();
    
    
    • 1
    • 2
    • 3

    Integer. valueOf()方法的作用

    Integer. valueOf()可以将基本类型int转换为包装类型Integer,或者将String转换成Integer,String如果为Null或“”都会报错

    ForeOrderController控制器实现购物车更新

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qtEbTvkz-1660310355893)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220812195218087.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AWO6fgyK-1660310355894)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220812195301363.png)]

     productOrderItemService.get(Integer.valueOf(key));
    
    • 1

    根据产品订单项的id获取数据库中的一条订单条目信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YiYByV0h-1660310355895)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220812195946955.png)]

    说明改订单已经生成了不在属于购物车

    Short number = Short.valueOf(orderItemString.getString(key));
                    if (number <= 0 || number > 500) {
                        logger.warn("订单项产品数量不合法!");
                        object.put("success", false);
                        return object.toJSONString();
                    }
    //获取前台提供的订单数判断时候合法符合规定
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在结算的时候先更新结算的状态

     //更新购物车订单项数量-ajax
        @ResponseBody
        @RequestMapping(value = "orderItem", method = RequestMethod.PUT, produces = "application/json;charset=utf-8")
        public String updateOrderItem(HttpSession session, Map<String, Object> map, HttpServletResponse response,
                                      @RequestParam String orderItemMap) {
            JSONObject object = new JSONObject();
            logger.info("检查用户是否登录");
            Object userId = checkUser(session);
            if (userId == null) {
                object.put("success", false);
                return object.toJSONString();
            }
    
            JSONObject orderItemString = JSON.parseObject(orderItemMap);
            Set<String> orderItemIDSet = orderItemString.keySet();
            if (orderItemIDSet.size() > 0) {
                logger.info("更新产品订单项数量");
                for (String key : orderItemIDSet) {
                    ProductOrderItem productOrderItem = productOrderItemService.get(Integer.valueOf(key));
                    if (productOrderItem == null || !productOrderItem.getProductOrderItem_user().getUser_id().equals(userId)) {
                        logger.warn("订单项为空或用户状态不一致!");
                        object.put("success", false);
                        return object.toJSONString();
                    }
                    if (productOrderItem.getProductOrderItem_order() != null) {
                        logger.warn("用户订单项不属于购物车,回到购物车页");
                        return "redirect:/cart";
                    }
                    Short number = Short.valueOf(orderItemString.getString(key));
                    if (number <= 0 || number > 500) {
                        logger.warn("订单项产品数量不合法!");
                        object.put("success", false);
                        return object.toJSONString();
                    }
                    double price = productOrderItem.getProductOrderItem_price() / productOrderItem.getProductOrderItem_number();
                    Boolean yn = productOrderItemService.update(new ProductOrderItem().setProductOrderItem_id(Integer.valueOf(key)).setProductOrderItem_number(number).setProductOrderItem_price(number * price));
                    if (!yn) {
                        throw new RuntimeException();
                    }
                }
                Object[] orderItemIDArray = orderItemIDSet.toArray();
                object.put("success", true);
                object.put("orderItemIDArray", orderItemIDArray);
                return object.toJSONString();
            } else {
                logger.warn("无订单项可以处理");
                object.put("success", false);
                return object.toJSONString();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    购物车结算时前台向后台发送的请求

    function create(obj) {
        obj = $(obj);
        if (!obj.hasClass("selected")) {
            return true;
        }
        var orderItemMap = {};
        var tr = $("input.cbx_select:checked").parents("tr.orderItem_info");
        tr.each(function () {
            var key = $(this).find(".input_orderItem").attr("name");
            orderItemMap[key] = $(this).find(".item_amount").children("input").val();
        });
        $.ajax({
            url: "/tmall/orderItem",
            type: "PUT",
            data: {
                "orderItemMap": JSON.stringify(orderItemMap)
            },
            traditional: true,
            success: function (data) {
                if (data.success) {
                    location.href = "/tmall/order/create/byCart?order_item_list=" + data.orderItemIDArray;
                    return true;
                } else {
                    alert("购物车商品结算异常,请稍候再试!");
                    location.href = "/tmall/cart";
                }
            },
            beforeSend: function () {
            },
            error: function () {
                alert("购物车商品结算异常,请稍候再试!");
                location.href = "/tmall/cart";
            }
        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    我们可以通过 JSON.stringify() 把 JavaScript 对象转换为字符串。

    JSON.stringify()语法

    JSON.stringify(value[, replacer [, space]])
    
    • 1

    JSON.stringify()不是只有一个参数,它最多可以有三个参数,只是一般后面两个用不到,所以我们会忽略它们。

    value

    将要序列化成 一个 JSON 字符串的值。

    replacer [可选]

    如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

    space [可选]

    指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。

    “orderItemMap”: JSON.stringify(orderItemMap)

    traditional: true,
    这个属性可以让ajax传数组,或对象

    修改购物车的状态完成之后发送请求

    /tmall/order/create/byCart?order_item_list=" + data.orderItemIDArray;

    说明创建多个订单(集合)

    跳转到购物车建立订单页

     //转到前台天猫-购物车订单建立页
        @RequestMapping(value = "order/create/byCart", method = RequestMethod.GET)
        public String goToOrderConfirmPageByCart(Map<String, Object> map,
                                                 HttpSession session, HttpServletRequest request,
                                                 @RequestParam(required = false) Integer[] order_item_list) throws UnsupportedEncodingException {
            logger.info("检查用户是否登录");
            Object userId = checkUser(session);
            User user;
            if (userId != null) {
                logger.info("获取用户信息");
                user = userService.get(Integer.parseInt(userId.toString()));
                map.put("user", user);
            } else {
                return "redirect:/login";
            }
            if (order_item_list == null || order_item_list.length == 0) {
                logger.warn("用户订单项数组不存在,回到购物车页");
                return "redirect:/cart";
            }
            logger.info("通过订单项ID数组获取订单信息");
            List<ProductOrderItem> orderItemList = new ArrayList<>(order_item_list.length);
            for (Integer orderItem_id : order_item_list) {
                orderItemList.add(productOrderItemService.get(orderItem_id));
            }
            logger.info("------检查订单项合法性------");
            if (orderItemList.size() == 0) {
                logger.warn("用户订单项获取失败,回到购物车页");
                return "redirect:/cart";
            }
            for (ProductOrderItem orderItem : orderItemList) {
                if(orderItem.getProductOrderItem_user().getUser_id().equals(userId)==false){
    //            if (orderItem.getProductOrderItem_user().getUser_id() != userId) {
                    logger.warn("用户订单项与用户不匹配,回到购物车页");
                    return "redirect:/cart";
                }
                if (orderItem.getProductOrderItem_order() != null) {
                    logger.warn("用户订单项不属于购物车,回到购物车页");
                    return "redirect:/cart";
                }
            }
            logger.info("验证通过,获取订单项的产品信息");
            double orderTotalPrice = 0.0;
            for (ProductOrderItem orderItem : orderItemList) {
                Product product = productService.get(orderItem.getProductOrderItem_product().getProduct_id());
                product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
                product.setSingleProductImageList(productImageService.getList(product.getProduct_id(), (byte) 0, new PageUtil(0, 1)));
                orderItem.setProductOrderItem_product(product);
                orderTotalPrice += orderItem.getProductOrderItem_price();
            }
            String addressId = "110000";
            String cityAddressId = "110100";
            String districtAddressId = "110101";
            String detailsAddress = null;
            String order_post = null;
            String order_receiver = null;
            String order_phone = null;
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    String cookieName = cookie.getName();
                    String cookieValue = cookie.getValue();
                    switch (cookieName) {
                        case "addressId":
                            addressId = cookieValue;
                            break;
                        case "cityAddressId":
                            cityAddressId = cookieValue;
                            break;
                        case "districtAddressId":
                            districtAddressId = cookieValue;
                            break;
                        case "order_post":
                            order_post = URLDecoder.decode(cookieValue, "UTF-8");
                            break;
                        case "order_receiver":
                            order_receiver = URLDecoder.decode(cookieValue, "UTF-8");
                            break;
                        case "order_phone":
                            order_phone = URLDecoder.decode(cookieValue, "UTF-8");
                            break;
                        case "detailsAddress":
                            detailsAddress = URLDecoder.decode(cookieValue, "UTF-8");
                            break;
                    }
                }
            }
            logger.info("获取省份信息");
            List<Address> addressList = addressService.getRoot();
            logger.info("获取addressId为{}的市级地址信息", addressId);
            List<Address> cityAddress = addressService.getList(null, addressId);
            logger.info("获取cityAddressId为{}的区级地址信息", cityAddressId);
            List<Address> districtAddress = addressService.getList(null, cityAddressId);
    
            map.put("orderItemList", orderItemList);
            map.put("addressList", addressList);
            map.put("cityList", cityAddress);
            map.put("districtList", districtAddress);
            map.put("orderTotalPrice", orderTotalPrice);
    
            map.put("addressId", addressId);
            map.put("cityAddressId", cityAddressId);
            map.put("districtAddressId", districtAddressId);
            map.put("order_post", order_post);
            map.put("order_receiver", order_receiver);
            map.put("order_phone", order_phone);
            map.put("detailsAddress", detailsAddress);
    
            logger.info("转到前台天猫-订单建立页");
            return "fore/productBuyPage";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    获取购物车中结算的信息用来创建订单

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dsncsw5U-1660310355896)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220812203303586.png)]

    return "fore/productBuyPage";
    
    • 1

    根据控制器中的信息判端出前端的返回地址

    //转到前台天猫-购物车订单建立页
    @RequestMapping(value = "order/create/byCart", method = RequestMethod.GET)
    public String goToOrderConfirmPageByCart(Map map,
                                             HttpSession session, HttpServletRequest request,
                                             @RequestParam(required = false) Integer[] order_item_list) throws UnsupportedEncodingException {
        logger.info("检查用户是否登录");
        
        return "fore/productBuyPage";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    【洛谷题解】P1036 [NOIP2002 普及组] 选数
    31.7.4 忽略指定的数据表
    Web3开发框架分析
    C++面试 -分布式架构-架构能力:分布式事务的学习
    进程间通信IPC-管道
    Android 11.0 无源码apk授予QUERY_ALL_PACKAGES权限
    自定义修改Discuz X3 今日发帖数量 昨日发帖数量 帖子总数 会员总数
    java版Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码
    [postgresql]postgresqlg使用enerate_series() 函数补全统计
    SQL慢?吐血整理MySQL中Explain分析工具
  • 原文地址:https://blog.csdn.net/weixin_46167190/article/details/126311654