此文檔是根據上課流程記錄,更多細節及圖片請參見劉老師的專欄java
《cgb2008-京淘day05》ajax
子節點的加載依賴於父節點的狀態redis
i. 用戶在默認的條件下若是沒有展開子節點則不會發出請求spring
ii. 當用戶打開封閉的節點時,會將當前節點的id做爲參數,向服務器發送請求數據庫
編輯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; }
編輯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; }
商品的新增後端
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); }
參數自動填充功能
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); } }
全局異常處理機制
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(); } }
商品分類名稱的回顯
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); })
商品修改
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); }
商品刪除
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>
i. 業務需求
當用戶點擊上架或者下架按鈕時,須要動態修改狀態信息。要求用一個方法實現。
1) url:/item/{instock},/item/{reself};2) 參數:id
ii. 下架status=2,上架status=1