JavaWeb從新手到入門(五)Spring Mybatis EasyUI實現商品列表
參考:《傳智播客-淘淘商城》
一、商品列表功能
商品列表功能是後端維護購物網站的商品的功能,提供了顯示、新增、編輯、刪除、下架和上架功能,顯示如下:
二、顯示功能的實現
開啟查詢商品後,後端首先按照分頁刷新出商品的資訊,因此顯示功能是第一步。
2.1 前端程式碼實現
前端程式碼的實現上主要包括介面顯示和訪問動作兩項。介面顯示採用easyui-datagrid控制元件實現,控制元件的程式碼如下:
控制元件附帶的動作為“GET”,url為“/item/list”,且附帶引數為“page=1&rows=30”<table class="easyui-datagrid" id="itemList" title="商品列表" data-options="singleSelect:false,collapsible:true,pagination:true,url:'/item/list',method:'get',pageSize:30,toolbar:toolbar"> <thead> <tr> <th data-options="field:'ck',checkbox:true"></th> <th data-options="field:'id',width:60">商品ID</th> <th data-options="field:'title',width:200">商品標題</th> <th data-options="field:'cid',width:100">葉子類目</th> <th data-options="field:'sellPoint',width:100">賣點</th> <th data-options="field:'price',width:70,align:'right',formatter:TAOTAO.formatPrice">價格</th> <th data-options="field:'num',width:70,align:'right'">庫存數量</th> <th data-options="field:'barcode',width:100">條形碼</th> <th data-options="field:'status',width:60,align:'center',formatter:TAOTAO.formatItemStatus">狀態</th> <th data-options="field:'created',width:130,align:'center',formatter:TAOTAO.formatDateTime">建立日期</th> <th data-options="field:'updated',width:130,align:'center',formatter:TAOTAO.formatDateTime">更新日期</th> </tr> </thead> </table>
頁數隨著資料網格下方的頁碼變化,前端發生翻頁動作時,向後端重新發送請求,這需要後端進行處理。
2.2 後端程式碼實現
與前端程式碼對應,後端需要對“/item/list?page=1&rows=30”的url做出相應,分為如下步驟:
1. 在priv.ality.common中建立pojo物件,用於定義EasyUIDataGrid的資料物件,資料獲取和更新時都會用到。
該類中包含了EasyUIDataGrid中需要用到的資料和資料長度。package priv.ality.utils; import java.util.List; public class EasyUIDataGridResult { private long total; private List<?> rows; public long getTotal() { return total; } public void setTotal(long total) { this.total = total; } public List<?> getRows() { return rows; } public void setRows(List<?> rows) { this.rows = rows; } }
2. 在priv.ality.service.ItemService中宣告資料更新方法getItemList
3. 在priv.ality.service.impl.ItemServiceImpl類中新增方法的實現:package priv.ality.service; import priv.ality.pojo.TbItem; import priv.ality.utils.EasyUIDataGridResult; import java.util.List; public interface ItemService { TbItem getItemById(Long itemId); EasyUIDataGridResult getItemList(int page, int rows); }
@Override
public EasyUIDataGridResult getItemList(int page, int rows) {
//分頁處理
PageHelper.startPage(page, rows);
//執行查詢
TbItemExample example = new TbItemExample();
List<TbItem> list = itemMapper.selectByExample(example);
//取分頁資訊
PageInfo<TbItem> pageInfo = new PageInfo<>(list);
//返回處理結果
EasyUIDataGridResult result = new EasyUIDataGridResult();
result.setTotal(pageInfo.getTotal());
result.setRows(list);
return result;
}
該方法使用了PageHelper庫提供Mybatis的分頁功能,並使用EasyUIDataGrid物件作為返回值返回給DataGrid控制元件,由控制元件進行抽取和
@RequestMapping("/item/list")
@ResponseBody
private EasyUIDataGridResult getItemList(Integer page, Integer rows) {
return itemService.getItemList(page, rows);
}
controller中通過呼叫itemService中的getItemList方法提供資料完成功能。
三、新增功能
商品列表除了基本的顯示功能之外,還提供資料的增刪查改,有一個工具欄“商品列表”用以提供快捷操作:
商品列表的原始碼如下:
var toolbar = [{
text:'新增',
iconCls:'icon-add',
handler:function(){ ; }
},{
text:'編輯',
iconCls:'icon-edit',
handler:function(){ ; }
},{
text:'刪除',
iconCls:'icon-cancel',
handler:function(){ ; }
},'-',{
text:'下架',
iconCls:'icon-remove',
handler:function(){ ; }
},{
text:'上架',
iconCls:'icon-remove',
handler:function(){ ; }
}];
當前程式碼只包含了顯示樣式,本篇文章只涉及“新增功能"
新增功能與Menu-Tree中的功能保持一致,當點選“新增”按鈕時,頁面跳轉到“新增商品”頁面:
跳轉過程的程式碼(即“商品列表”中“新增”工具的程式碼)如下:
{
text:'新增',
iconCls:'icon-add',
handler:function(){
$(".tree-title:contains('新增商品')").parent().click();
}
}
$(".tree-title:contains('新增商品')").parent().click();
如上提供了跳轉到“新增商品”的操作,下面分析該操作。
“新增商品”頁見上,頁面主要實現的內容有:
- 1. 商品類目的選擇
- 2. 商品標題、價格和數量的必選項設定
- 3. 商品圖片的上傳
- 4. 富文字商品描述
首先給出新增商品頁的佈局程式碼:
<div style="padding:10px 10px 10px 10px">
<form id="itemAddForm" class="itemForm" method="post">
<table cellpadding="5">
<tr>
<td>商品類目:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>
<input type="hidden" name="cid" style="width: 280px;"></input>
</td>
</tr>
<tr>
<td>商品標題:</td>
<td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td>
</tr>
<tr>
<td>商品賣點:</td>
<td><input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;"></input></td>
</tr>
<tr>
<td>商品價格:</td>
<td><input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" />
<input type="hidden" name="price"/>
</td>
</tr>
<tr>
<td>庫存數量:</td>
<td><input class="easyui-numberbox" type="text" name="num" data-options="min:1,max:99999999,precision:0,required:true" /></td>
</tr>
<tr>
<td>條形碼:</td>
<td>
<input class="easyui-textbox" type="text" name="barcode" data-options="validType:'length[1,30]'" />
</td>
</tr>
<tr>
<td>商品圖片:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上傳圖片</a>
<input type="hidden" name="image"/>
</td>
</tr>
<tr>
<td>商品描述:</td>
<td>
<textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>
</td>
</tr>
<tr class="params hide">
<td>商品規格:</td>
<td>
</td>
</tr>
</table>
<input type="hidden" name="itemParams"/>
</form>
<div style="padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a>
</div>
</div>
下面依次對四個方面進行實現。
四、新增功能的實現
4.1 商品類目
前端程式碼
商品類目的前端佈局程式碼如下:
<tr>
<td>商品類目:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>
<input type="hidden" name="cid" style="width: 280px;"></input>
</td>
</tr>
該佈局中“選擇商品”的屬性為“easyui-linkbutton”,該按鈕並沒有註冊OnClick事件,而是註冊一個為“selectItemCat”的樣式,該樣式由/js/common.js中,定義如下:
// 初始化選擇類目元件
initItemCat : function(data){
$(".selectItemCat").each(function(i,e){
var _ele = $(e);
if(data && data.cid){
_ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
}else{
_ele.after("<span style='margin-left:10px;'></span>");
}
_ele.unbind('click').click(function(){
$("<div>").css({padding:"5px"}).html("<ul>")
.window({
width:'500',
height:"450",
modal:true,
closed:true,
iconCls:'icon-save',
title:'選擇類目',
onOpen : function(){
var _win = this;
$("ul",_win).tree({
url:'/item/cat/list',
animate:true,
onClick : function(node){
if($(this).tree("isLeaf",node.target)){
// 填寫到cid中
_ele.parent().find("[name=cid]").val(node.id);
_ele.next().text(node.text).attr("cid",node.id);
$(_win).window('close');
if(data && data.fun){
data.fun.call(this,node);
}
}
}
});
},
onClose : function(){
$(this).window("destroy");
}
}).window('open');
});
});
},
該樣式類selectItemCat使用each對所有繫結該事件的樣式迴圈初始化,在該類首先對click事件進行解綁,然後繫結方法function:
$("<div>").css({padding:"5px"}).html("<ul>")
.window({
width:'500',
height:"450",
modal:true,
closed:true,
iconCls:'icon-save',
title:'選擇類目',
onOpen : function(){
var _win = this;
$("ul",_win).tree({
url:'/item/cat/list',
animate:true,
onClick : function(node){
if($(this).tree("isLeaf",node.target)){
// 填寫到cid中
_ele.parent().find("[name=cid]").val(node.id);
_ele.next().text(node.text).attr("cid",node.id);
$(_win).window('close');
if(data && data.fun){
data.fun.call(this,node);
}
}
}
});
},
onClose : function(){
$(this).window("destroy");
}
}).window('open');
該動作建立並開啟一個模態視窗,該視窗的開啟動作中進行AJAX請求向伺服器請求資料,並將資料填充到easy-ui的非同步樹形控制元件中,設定url為'/item/cat/list',這也需要伺服器端對該URL進行相應。
easy-ui中的非同步tree控制元件初始化時首先讀取當前樹的節點,當展開一個封閉的節點時如果節點未曾載入,則在url中新增請求引數:節點ID,然後向伺服器發起請求,伺服器端進行相應時為JSON資料,且具備結構要求:
[{
"id": 1,
"text": "Node 1",
"state": "closed"
}
{
"id": 2,
"text": "Node 2",
"state": "closed"
}
]
state的值要求如下:如果當前節點為父節點,state應為“closed”、如果是葉子節點則應該為“open”。
前端程式碼分析完畢,對於JQuery的API熟練度不夠,還沒發自己寫出來一個=_=!
後端程式碼
1. 建立EasyUITreeNode這個pojo物件
EasyUITreeNode用於定義樹形節點的各個節點資料,由於類比較基礎,放置在ality-common工程中:
public class EasyUITreeNode {
private long id;
private String text;
private String state;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
2. 建立ItemCatService介面,代表商品新增相關的服務
package priv.ality.service;
import priv.ality.utils.EasyUITreeNode;
import java.util.List;
public interface ItemCatService {
public List<EasyUITreeNode> getItemCatList(long parentId);
}
該服務的方法getItemCatList使用引數parentId對應前端分析的url中帶來的引數,返回值為EasyUITreeNode的List物件。
3. 建立該介面的實現ItemCatServiceImpl:package priv.ality.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import priv.ality.mapper.TbItemCatMapper;
import priv.ality.pojo.TbItemCat;
import priv.ality.pojo.TbItemCatExample;
import priv.ality.service.ItemCatService;
import priv.ality.utils.EasyUITreeNode;
import java.util.ArrayList;
import java.util.List;
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private TbItemCatMapper itemCatMapper;
@Override
public List<EasyUITreeNode> getItemCatList(long parentId) {
// 根據parentId查詢分類列表
TbItemCatExample example = new TbItemCatExample();
//設定查詢條件
TbItemCatExample.Criteria criteria = example.createCriteria();
criteria.andParentIdEqualTo(parentId);
//執行查詢
List<TbItemCat> list = itemCatMapper.selectByExample(example);
//轉換成EasyUITreeNode列表
List<EasyUITreeNode> resultList = new ArrayList<>();
for (TbItemCat tbItemCat : list) {
//建立一個節點物件
EasyUITreeNode node = new EasyUITreeNode();
node.setId(tbItemCat.getId());
node.setText(tbItemCat.getName());
node.setState(tbItemCat.getIsParent()?"closed":"open");
//新增到列表中
resultList.add(node);
}
return resultList;
}
}
該實現中使用Example物件和Criteria物件設定查詢條件,獲取了ParentId等於入參的所有結果,並按照非同步Tree要求的格式進行封裝後返回結果。
4. 在Controller中新增方法接受引數並返回結果(JSON資料)。
package priv.ality.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import priv.ality.service.ItemCatService;
import priv.ality.utils.EasyUITreeNode;
import java.util.List;
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
@RequestMapping("/list")
@ResponseBody
public List<EasyUITreeNode> getItemCatList(@RequestParam(value="id",defaultValue = "0")Long parentId){
return itemCatService.getItemCatList(parentId);
}
}
功能完成結果如下:
如上可見,商品類目選擇功能已經得到實現。
ps:入職新公司,技術棧發生變更,由JavaWeb轉大資料方向,語言轉向Ruby和Node.js,所以下面就暫時暫停更新這個系列的文章啦,有的閒工夫再來~