【校园商铺SSM-25】商品编辑--Controller+View+前后端联调的实现

标签: 校园商铺项目实战

1. Controller层的实现

1. getProductById

@RequestMapping(value = "/getproductbyid",method = RequestMethod.GET)
@ResponseBody
private Map<String,Object> getProductById(@RequestParam Long productId){
    Map<String,Object> modelMap = new HashMap<>();
    //非空判断
    if(productId>-1){
        //获取商品信息
        Product product = productService.getProductById(productId);
        //获取该店铺下的商品类别列表
        List<ProductCategory> productCategoryList
                = productCategoryService.getProductCategoryList(product.getShop().getShopId());
        modelMap.put("product",product);
        modelMap.put("productCategoryList",productCategoryList);
        modelMap.put("success",true);
    }else{
        modelMap.put("success",false);
        modelMap.put("errMsg","empty producted");
    }
    return modelMap;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. modifyProduct

@RequestMapping(value = "/modifyproduct",method = RequestMethod.POST)
@ResponseBody
private Map<String,Object> modifyProduct(HttpServletRequest request){
    Map<String,Object> modelMap = new HashMap<>();
    //判断是商品编辑还是商品上下架
    boolean statusChange = HttpServletRequestUtil.getBoolean(request,"statusChange");
    //如果为商品编辑就进行验证码判断,后者不进行
    if(!statusChange && !CodeUtil.verifyCode(request)){
        modelMap.put("success",false);
        modelMap.put("errMsg","输入了错误的验证码");
        return modelMap;
    }

    //接收前端参数的变量的初始化,包括商品,缩略图,详情图列表实体类
    //1.图片
    MultipartHttpServletRequest multipartRequest = null;
    ImageHolder thumbnail = null;
    List<ImageHolder> productImgList = new ArrayList<>();
    //从Session中获取文件流
    CommonsMultipartResolver multipartResolver
            = new CommonsMultipartResolver(request.getSession().getServletContext());
    try {
        //如果请求中有文件流,那么取出相关的文件(包括缩略图和详情图)
        if(multipartResolver.isMultipart(request)){
            multipartRequest = (MultipartHttpServletRequest)request;
            //取出缩略图并构建ImageHolder对象
            CommonsMultipartFile thumbnailFile
                    = (CommonsMultipartFile)multipartRequest.getFile("thumbnail");
            thumbnail
                    = new ImageHolder(thumbnailFile.getOriginalFilename(),thumbnailFile.getInputStream());

            //取出详情图列表并构建List<ImageHolder>列表对象,最多支持6张图片上传
            for(int i=0;i<IMAGEMAXCOUNT;i++){
                CommonsMultipartFile productImgFile
                        = (CommonsMultipartFile)multipartRequest.getFile("productImg"+i);
                if(productImgFile!=null){
                    //如果取出的第i个详情图片不为空,那么将其加入详情图列表
                    ImageHolder productImg =
                            new ImageHolder(productImgFile.getOriginalFilename(),productImgFile.getInputStream());
                    productImgList.add(productImg);
                }else{
                    //如果取出的第i个详情图片文件为空,则终止循环
                    break;
                }
            }
        }
    } catch (Exception e) {
        modelMap.put("success",false);
        modelMap.put("errMsg",e.toString());
        return modelMap;
    }

    //2.商品实体类
    ObjectMapper mapper = new ObjectMapper();
    Product product = null;
    String productStr = HttpServletRequestUtil.getString(request,"productStr");
    try {
        //尝试获取前台穿来的表单将其装换为Product实体类
        product = mapper.readValue(productStr,Product.class);
    } catch (Exception e) {
        modelMap.put("success",false);
        modelMap.put("errMsg",e.toString());
        return modelMap;
    }
    //进行商品信息更新
    if(product!=null){
        try {
            //从session中获取当前店铺的id并赋值给product,减少对前端数据的依赖
            Shop currentShop = (Shop)request.getSession().getAttribute("currentShop");
            product.setShop(currentShop);
            //开始对商品信息变更操作
            ProductExecution productExecution
                    = productService.modifyProduct(product,thumbnail,productImgList);
            if(productExecution.getState()==ProductStateEnum.SUCCESS.getState()){
                modelMap.put("success",true);
            }else{
                modelMap.put("success",false);
                modelMap.put("errMsg",productExecution.getStateInfo());
            }
        } catch (ProductOperationException e) {
            modelMap.put("success",false);
            modelMap.put("errMsg",e.toString());
            return modelMap;
        }
    }else{
        modelMap.put("success",false);
        modelMap.put("errMsg","请输入商品信息");
    }
    return modelMap;
}

2. View层的实现

productoperation.js文件:

$(function(){
    //通过url是否含有productId来判断是添加商品还是编辑
    var productId = getQueryString('productId');
    // 标示符  productId非空则为true即编辑,否则为添加商品
    var isEdit = productId ? true : false ;

    // 商品添加URL 用于提交
    var addProductURL = '/o2o/shopadmin/addproduct';
    // 商品编辑URL 用于提交
    var editProductURL = '/o2o/shopadmin/modifyproduct?productId=' + productId;
    // 获取商品初始化信息的URL  根据页面原型只需要获取productCategory即可,后台调用之前写好的路由方法即可
    var categoryInfoURL = '/o2o/shopadmin/getproductcategorylist';
    // 商品编辑URL 用于从后台加载该product的基本信息,页面展示用
    var productInitURL = '/o2o/shopadmin/getproductbyid?productId=' + productId;



    // 通过标示符,确定调用的方法
    if(isEdit){
        // 为true,则根据productId调用获取product信息的方法
        showEditProductPage(productId);
    }else{
        // 为false,则初始化新增product页面
        showAddProductPage();
    }

    /**
     * 始化新增product页面
     *
     * 根据页面原型和数据模型,需要加载该shop对应的productCategory信息(shop信息从服务端session中获取)
     */
    function showAddProductPage(){
        $.getJSON(categoryInfoURL,
            function(data){
                if(data.success){
                    // 设置product_category
                    var productCategoryList = data.data;
                    var productCategoryTempHtml = '';
                    productCategoryList.map(function(item, index) {
                        productCategoryTempHtml
                            += '<option data-value="'
                            + item.productCategoryId
                            + '">'
                            + item.productCategoryName
                            + '</option>';
                    });
                    $('#product-category').html(productCategoryTempHtml);
                }else{
                    $.toast(data.errMsg)
                }
            });
    };

    /**
     * 点击控件的最后一个且图片数量小于6个的时候,生成一个选择框
     */
    $('.detail-img-div').on('change', '.detail-img:last-child', function() {
        if ($('.detail-img').length < 6) {
            $('#detail-img').append('<input type="file" class="detail-img">');
        }
    });


    /**
     * 编辑页面调用的function
     */
    function showEditProductPage(productId){
        $.getJSON(
            productInitURL,
            function(data) {
                if (data.success) {
                    var product = data.product;
                    $('#product-name').val(product.productName);
                    $('#product-desc').val(product.productDesc);
                    $('#priority').val(product.priority);
                    $('#normal-price').val(product.normalPrice);
                    $('#promotion-price').val(
                        product.promotionPrice);

                    var optionHtml = '';
                    var optionArr = data.productCategoryList;
                    var optionSelected = product.productCategory.productCategoryId;
                    optionArr.map(function(item, index) {
                        var isSelect = optionSelected === item.productCategoryId ? 'selected'
                            : '';
                        optionHtml += '<option data-value="'
                            + item.productCategoryId
                            + '"'
                            + isSelect
                            + '>'
                            + item.productCategoryName
                            + '</option>';
                    });
                    $('#product-category').html(optionHtml);
                }
            });
    };

    /**
     * 提交按钮的响应时间,分别对商品添加和商品编辑做不同的相应
     */
    $('#submit').click(
        function(){
            // 创建商品Json对象,并从表单对象中获取对应的属性值
            var product = {};

            // 如果是编辑操作,需要传入productId
            if(isEdit){
                product.productId = productId;
            }

            product.productName = $('#product-name').val();
            product.productDesc = $('#product-desc').val();

            // 获取商品的特定目录值
            product.productCategory = {
                productCategoryId : $('#product-category').find('option').not(
                    function() {
                        return !this.selected;
                    }).data('value')
            };

            product.priority = $('#priority').val();
            product.normalPrice = $('#normal-price').val();
            product.promotionPrice = $('#promotion-price').val();

            // 生成表单对象用于接收参数并传递给后台
            var formData = new FormData();

            // 缩略图 (只有一张),获取缩略图的文件流
            var thumbnail = $('#small-img')[0].files[0];
            formData.append('thumbnail',thumbnail);

            // 图片详情
            $('.detail-img').map(
                function(index, item) {
                    // 判断该控件是否已经选择了文件
                    if ($('.detail-img')[index].files.length > 0) {
                        // 将第i个文件流赋值给key为productImgi的表单键值对里
                        formData.append('productImg' + index,
                            $('.detail-img')[index].files[0]);
                    }
                });
            // 将product 转换为json ,添加到forData
            formData.append('productStr', JSON.stringify(product));

            // 获取表单中的验证码
            var verifyCodeActual = $('#j_captcha').val();
            if (!verifyCodeActual) {
                $.toast('请输入验证码!');
                return;
            }
            formData.append("verifyCodeActual", verifyCodeActual);

            // 使用ajax异步提交
            $.ajax({
                url: isEdit?editProductURL:addProductURL,
                type: 'POST' ,
                data : formData,
                contentType : false,
                processData : false,
                cache : false,
                success: function(data){
                    if (data.success) {
                        $.toast('提交成功!');
                        $('#captcha_img').click();
                    } else {
                        $.toast('提交失败!');
                        $('#captcha_img').click();
                    }
                }
            });
        });
});

在这里插入图片描述

3. 前后端联合调试

在前端打上5个断点:
在这里插入图片描述
进入前端调试页面后在后端打一个断点:
在这里插入图片描述
按f10进行步调,按f8跳过进入下一个断点进行调试,进入后端按f8进行步调,调试完按f9结束调试
在这里插入图片描述
在这里插入图片描述

版权声明:本文为qq_42764468原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42764468/article/details/104366417

智能推荐

RIP/DHCP/ACL综合实验

组播: 加入组的组成员才会接受到消息,只需要将流量发送一次到组播地址 减少控制面流量,减少头部复制, RIP1  广播   有类  不支持认证 RIP2  组播   无类  (支持VLAN)、支持认证 所有距离矢量路由协议:具有距离矢量特征的协议,都会在边界自动汇总 控制平面  路由的产生是控制平面的流量 数据平面  ...

【Sublime】使用 Sublime 工具时运行python文件

使用 Sublime 工具时报Decode error - output not utf-8解决办法   在菜单中tools中第四项编译系统 内最后一项增添新的编译系统 自动新建 Python.sublime-build文件,并添加"encoding":"cp936"这一行,保存即可 使用python2 则注释encoding改为utf-8 ctr...

java乐观锁和悲观锁最底层的实现

1. CAS实现的乐观锁 CAS(Compare And Swap 比较并且替换)是乐观锁的一种实现方式,是一种轻量级锁,JUC 中很多工具类的实现就是基于 CAS 的,也可以理解为自旋锁 JUC是指import java.util.concurrent下面的包, 比如:import java.util.concurrent.atomic.AtomicInteger; 最终实现是汇编指令:lock...

Python 中各种imread函数的区别与联系

  原博客:https://blog.csdn.net/renelian1572/article/details/78761278 最近一直在用python做图像处理相关的东西,被各种imread函数搞得很头疼,因此今天决定将这些imread总结一下,以免以后因此犯些愚蠢的错误。如果你正好也对此感到困惑可以看下这篇总结。当然,要了解具体的细节,还是应该 read the fuc...

用栈判断一个字符串是否平衡

注: (1)本文定义:左符号:‘(’、‘[’、‘{’…… 右符号:‘)’、‘]’、‘}’……. (2)所谓的字符串的符号平衡,是指字符串中的左符号与右符号对应且相等,如字符串中的如‘(&r...

猜你喜欢

JAVA环境变量配置

位置 计算机->属性->高级系统设置->环境变量 方式一 用户变量新建path 系统变量新建classpath 方式二 系统变量 新建JAVA_HOME,值为JDK路径 编辑path,前加 方式三 用户变量新建JAVA_HOME 此路径含lib、bin、jre等文件夹。后运行tomcat,eclipse等需此变量,故最好设。 用户变量编辑Path,前加 系统可在任何路径识别jav...

常用的伪类选择器

CSS选择器众多 CSS选择器及权重计算 最常用的莫过于类选择器,其它的相对用的就不会那么多了,当然属性选择器和为类选择器用的也会比较多,这里我们就常用的伪类选择器来讲一讲。 什么是伪类选择器? CSS伪类是用来添加一些选择器的特殊效果。 常用的为类选择器 状态伪类 我们中最常见的为类选择器就是a标签(链接)上的为类选择器。 当我们使用它们的时候,需要遵循一定的顺序问题,否则将可能出现bug 注意...

ButterKnife的使用介绍及原理探究(六)

前面分析了ButterKnife的源码,了解其实现原理,那么就将原理运用于实践吧。 github地址:       点击打开链接 一、自定义注解 这里为了便于理解,只提供BindView注解。 二、添加注解处理器 添加ViewInjectProcessor注解处理器,看代码, 这里分别实现了init、getSupportedAnnotationTypes、g...

1.写一个程序,提示输入两个字符串,然后进行比较,输出较小的字符串。考试复习题库1|要求:只能使用单字符比较操作。

1.写一个程序,提示输入两个字符串,然后进行比较,输出较小的字符串。 要求只能使用单字符比较操作。 参考代码: 实验结果截图:...

小demo:slideDown()实现二级菜单栏下拉效果

效果如下,鼠标经过显示隐藏的二级菜单栏 但是这样的时候会存在一个问题,就是鼠标快速不停移入移出会导致二级菜单栏闪屏现象,一般需要使用stop()来清除事件  ...