day 05 商品模块CRUD

此文档是依据上课流程记录,更多细节及图片请参见刘老师的专栏

江哥的专栏

《cgb2008-京淘day05》

一. 实现商品分类的展示
  1. 树形构造展示

    子节点的加载依赖于父节点的状态

    i. 用户在默认的条件下如果没有开展子节点则不会发出请求

    ii. 当用户关上关闭的节点时,会将以后节点的id作为参数,向服务器发送申请

  2. 编辑ItemCatController

    /* 业务需要:实现商品分类树形构造的展现    url: http://localhost:8091/item/cat/list    参数: id = 父级节点的id    返回值: List<EasyUITree>*/@RequestMapping("/list")public List<EasyUITree> showTree(Long id){    //临时只查问一级菜单信息    Long parentId = (id==null)?0L:id;    //数据库记录 ItemCat对象,页面中要的数据 EasyUITree    //须要将pojo对象转换为vo对象 get/set...    List<EasyUITree> list = itemCatService.findAllCat();    return list;}
  3. 编辑ItemCatService

    /* 依据parentId获取List汇合   将这个汇合转换为vo的汇合 */@Overridepublic List<EasyUITree> findAllCat(long parentId) {    List<EasyUITree> easyUITrees = new ArrayList<>();    QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();    queryWrapper.eq("parent_id", parentId);    List<ItemCat> itemCats  = itemCatMapper.selectList(queryWrapper);    itemCats.forEach(item->{        EasyUITree easyUITree = new EasyUITree();        easyUITree.setId(item.getId()).setText(item.getName());        if (item.getIsParent())            easyUITree.setState("closed");        else            easyUITree.setState("open");        easyUITrees.add(easyUITree);    });    return easyUITrees;}
二. 实现商品CRUD操作
  1. 商品的新增

    i. 业务逻辑

    1) 申请的url:http://localhost:8091/item/save

    2) 用户的参数:cid=76&title=1&sellPoint=2&priceView=3.00&price=300&num=4&barcode=5&image&itemDesc=6&itemParams=[]

    3) JS代码

    function submitForm(){   //表单校验   if(!$('#itemAddForm').form('validate')){      $.messager.alert('提醒','表单还未填写实现!');      return ;   }   //转化价格单位,将元转化为分   //$("XX").val()取值, $("XX").val(100)赋值   $("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);   itemAddEditor.sync();//将输出的内容同步到多行文本中      var paramJson = [];   $("#itemAddForm .params li").each(function(i,e){      var trs = $(e).find("tr");      var group = trs.eq(0).text();      var ps = [];      for(var i = 1;i<trs.length;i++){         var tr = trs.eq(i);         ps.push({            "k" : $.trim(tr.find("td").eq(0).find("span").text()),            "v" : $.trim(tr.find("input").val())         });      }      paramJson.push({         "group" : group,         "params": ps      });   });   paramJson = JSON.stringify(paramJson);//将对象转化为json字符串      $("#itemAddForm [name=itemParams]").val(paramJson);      /*$.post/get(url,JSON,function(data){....})        ?id=1&title="天龙八部&key=value...."   */   //alert($("#itemAddForm").serialize());   //参数的写法:   //{key1:value1,key2:value2}   //?key1=value1&key2=value2   //.serialize() - API   $.post("/item/save",$("#itemAddForm").serialize(), function(data){      if(data.status == 200){         $.messager.alert('提醒','新增商品胜利!');      }else{         $.messager.alert("提醒","新增商品失败!");      }   });}

    ii. 编辑SysResult VO对象

    @Data@Accessors(chain = true)@NoArgsConstructor@AllArgsConstructorpublic class SysResult {    private Integer status; //200示意胜利 201示意失败    private String msg; //服务器给用户的提示信息    private Object data; //服务器返回给用户的数据    //封装工具API    public static SysResult fail(){        return new SysResult(201,"服务器调用异样",null);    }    public static SysResult success(){        return new SysResult(200,"业务执行胜利",null);    }    public static SysResult success(Object data){        return new SysResult(200,"业务执行胜利",data);    }    public static SysResult success(String msg,Object data){        return new SysResult(200,msg,data);    }}

    iii. 编辑ItemController

    /* 业务:商品的新增操作   url: http://localhost:8091/item/save   参数: 整个表单进行提交 应用对象接管   返回值: SysResult*/@RequestMapping("/save")@ResponseBodypublic SysResult saveItem(Item item){   try {      itemService.saveItem(item);      return SysResult.success();   }catch (Exception e){      e.printStackTrace();      return SysResult.fail();   }}

    iv. 编辑ItemServiceImpl

    @Override@Transactionalpublic void saveItem(Item item) {   Date date = new Date();   item.setStatus(1).setCreated(date).setUpdated(date);   itemMapper.insert(item);}
  2. 参数主动填充性能

    i. 业务需要:在用户入库/更新操作时,是否实现工夫的主动填充,简化用户的操作步骤。

    ii. 编辑BasePojo,增加注解

    //pojo基类,实现2个工作:2个日期,实现序列化@Data@Accessors(chain=true)public class BasePojo implements Serializable{   @TableField(fill = FieldFill.INSERT)  //新增操作时,增加数据   private Date created;   @TableField(fill = FieldFill.INSERT_UPDATE)  //新增更新操作时,增加数据   private Date updated;}

    iii. 编辑MyMetaObjectHandler配置类

    @Slf4j@Component  //将对象交给容器治理public class MyMetaObjectHandler implements MetaObjectHandler {       //实现入库和更新操作的主动赋值    @Override    public void insertFill(MetaObject metaObject) {        Date date = new Date();        this.setInsertFieldValByName("created", date, metaObject);        this.setInsertFieldValByName("updated",date,metaObject);    }    @Override    public void updateFill(MetaObject metaObject) {        Date date = new Date();        this.setInsertFieldValByName("updated", date, metaObject);    }}
  3. 全局异样解决机制

    i. 阐明

    1) 如果将大量的异样解决写到代码中,尽管能够保障程序稳固的运行,然而代码的构造十分的凌乱;

    2) 异样时程序运行状态的一种体现,如果没有一种对立的规定来解决异样,则程序一旦出错问题无奈定位;

    3) 问:异样从哪里接管?异样应该在Controll层进行拦挡

    Mapper --> Service --> Controller -->用户

    ii. 引入jar包

    <!--增加httpClient jar包 --><dependency>    <groupId>org.apache.httpcomponents</groupId>    <artifactId>httpclient</artifactId></dependency><!--引入dubbo配置 --><dependency>    <groupId>com.alibaba.boot</groupId>    <artifactId>dubbo-spring-boot-starter</artifactId>    <version>0.2.0</version></dependency>--><!--增加Quartz的反对 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-quartz</artifactId></dependency>--><!-- 引入aop反对 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-aop</artifactId></dependency><!--spring整合redis --><dependency>    <groupId>redis.clients</groupId>    <artifactId>jedis</artifactId></dependency><dependency>    <groupId>org.springframework.data</groupId>    <artifactId>spring-data-redis</artifactId></dependency>

    iii. 编辑SystemException切面

    //@Aspect//@Component@RestControllerAdvice //AOP+异样告诉public class SystemException {    //当遇到某种类型的异样时才会执行    @ExceptionHandler({RuntimeException.class, SQLException.class})    public Object exception(){        return SysResult.fail();    }}
  4. 商品分类名称的回显

    i. 须要将cid展示为具体的名称

    ii. 编辑item_list页面的js

    /* 实现商品分类名称的回显    1.获取商品分类的id    2.发送ajax申请    3.将后果在指定地位展示*/let cid = data.cid;$.get("/item/cat/queryItemName",{"itemCatId":cid},function(data){    //data代表返回值后果 -- 商品分类名称    $("#itemeEditForm input[name='cid']").prev("span").text(data);})
  5. 商品批改

    i. 查看页面的JS

    $.post("/item/update",$("#itemeEditForm").serialize(), function(data){   if(data.status == 200){      $.messager.alert('提醒','批改商品胜利!','info',function(){         $("#itemEditWindow").window('close');         $("#itemList").datagrid("reload");      });   }else{      $.message.alert("提醒",data.msg);   }});

    ii. 编辑ItemController

    /* 业务:商品的批改操作   url: http://localhost:8091/item/update   参数: 整个表单进行提交 应用对象接管   返回值: SysResult*/@RequestMapping("/update")@ResponseBodypublic SysResult updateItem(Item item){   itemService.updateItem(item);   return SysResult.success();}

    iii. 编辑ItemServiceImpl

    @Override@Transactionalpublic void updateItem(Item item) {   itemMapper.updateById(item);}
  6. 商品删除

    i. 业务剖析

    当用户选中数据之后,点击删除按钮时应该执行删除的操作,利用MP的形式实现数据删除,利用手写SQL的模式,手动删除数据。

    1) url: /item/delete;2) 参数:Integer[] ids;3) 页面JS的剖析

    ii. 编辑ItemController

    /* 业务:商品的删除操作    url: http://localhost:8091/item/delete    参数: Integer[] ids    返回值: SysResult    常识扩大:     问题:页面中<input name="id" value="100"/>参数是如何承受的,底层实现是什么? 客户端 --> Servlet[http协定]Request对象 <-- 后端服务器(取值)req.getParameter("id") */@RequestMapping("/delete")@ResponseBodypublic SysResult deleteItems(Integer[] ids/*,HttpServletRequest req, HttpResponse resp*/){    itemService.deleteItems(ids);    return SysResult.success();}

    iii. 编辑ItemServiceImpl

    @Override@Transactionalpublic void deleteItems(Integer[] ids) {   //itemMapper.deleteBatchIds(Arrays.asList(ids)); //MP   itemMapper.deleteItems(Arrays.asList(ids)); //手写SQL}

    iv. 编辑ItemMapper(.xml)

    void deleteItems(@Param("ids") List<Integer> ids);
    <!-- 1.实现商品删除         知识点:MyBatis参数传递问题     起因: MyBatis底层实现时通过下标取值     核心思想:将多值转换为单值     罕用办法:1.应用对象封装,2.能够封装为数组,3.Map汇合     1.#{对象的属性},2.array/list,3.#{key}--><delete id="deleteItems" parameterType="list">   DELETE FROM tb_item   WHERE id IN   <foreach collection="ids" separator="," open="(" close=")" item="id">      #{id}   </foreach></delete>
  7. 商品上架/下架操作

    i. 业务需要

    当用户点击上架或者下架按钮时,须要动静批改状态信息。要求用一个办法实现。

    1) url:/item/{instock},/item/{reself};2) 参数:id

    ii. 下架status=2,上架status=1

作业:实现商品上架/下架操作