第四階段筆記 Jingtao_day05

day 05 商品模塊CRUD

此文檔是根據上課流程記錄,更多細節及圖片請參見劉老師的專欄java

江哥的專欄

cgb2008-京淘day05ajax

一. 完成商品分類的展示
  1. 樹形結構展示

    子節點的加載依賴於父節點的狀態redis

    i. 用戶在默認的條件下若是沒有展開子節點則不會發出請求spring

    ii. 當用戶打開封閉的節點時,會將當前節點的id做爲參數,向服務器發送請求數據庫

  2. 編輯ItemCatControllerapache

    /* 業務需求:實現商品分類樹形結構的展現
        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. 編輯ItemCatServicejson

    /* 根據parentId獲取List集合
       將這個集合轉換爲vo的集合
     */
    @Override
    public 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
    @AllArgsConstructor
    public 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")
    @ResponseBody
    public SysResult saveItem(Item item){
       try {
          itemService.saveItem(item);
          return SysResult.success();
       }catch (Exception e){
          e.printStackTrace();
          return SysResult.fail();
       }
    }

    iv. 編輯ItemServiceImpl

    @Override
    @Transactional
    public 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")
    @ResponseBody
    public SysResult updateItem(Item item){
       itemService.updateItem(item);
       return SysResult.success();
    }

    iii. 編輯ItemServiceImpl

    @Override
    @Transactional
    public 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")
    @ResponseBody
    public SysResult deleteItems(Integer[] ids/*,HttpServletRequest req, HttpResponse resp*/){
        itemService.deleteItems(ids);
        return SysResult.success();
    }

    iii. 編輯ItemServiceImpl

    @Override
    @Transactional
    public 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

做業:實現商品上架/下架操做
相關文章
相關標籤/搜索