1. 程式人生 > >複習電商筆記-9

複習電商筆記-9

 

後臺首頁

 

 

通用的頁面跳轉

package com.jt.manage.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 通用的頁面跳轉控制器
 */
@RequestMapping(value = "/page")
@Controller
public class PageController {

    @RequestMapping(value = "/{pageName}")
    public String toPage(@PathVariable("pageName") String pageName) {
        return pageName;
    }

}

RESTFul方式請求

 

EasyUI富客戶端  

 

 

介紹:      http://www.jeasyui.net/

jQuery EasyUI 提供了用於建立跨瀏覽器網頁的完整的元件集合,包括功能強大的 datagrid(資料網格)、treegrid(樹形表格)、 panel(面板)、combo(下拉組合)等等。 使用者可以組合使用這些元件,也可以單獨使用其中一個。

外掛列表如下:

分類

外掛

Base

(基礎)

  • Parser 解析器
  • Easyloader 載入器
  • Draggable 可拖動
  • Droppable 可放置
  • Resizable 可調整尺寸
  • Pagination 分頁
  • Searchbox 搜尋框
  • Progressbar 進度條
  • Tooltip 提示框

Layout(佈局)

  • Panel 面板
  • Tabs 標籤頁/選項卡
  • Accordion
    摺疊面板
  • Layout 佈局

Menu(選單)與 Button(按鈕)

  • Menu 選單
  • Linkbutton 連結按鈕
  • Menubutton 選單按鈕
  • Splitbutton 分割按鈕

Form(表單)

  • Form 表單
  • Validatebox 驗證框
  • Combo 組合
  • Combobox 組合框
  • Combotree 組合樹
  • Combogrid 組合網格
  • Numberbox 數字框
  • Datebox 日期框
  • Datetimebox 日期時間框
  • Calendar 日曆
  • Spinner 微調器
  • Numberspinner 數值微調器
  • Timespinner 時間微調器
  • Slider 滑塊
  • textbox基礎文字框
  • filebox檔案上傳

Window(視窗)

  • Window 視窗
  • Dialog 對話方塊
  • Messager 訊息框

DataGrid(資料網格)與 Tree(樹)

  • Datagrid 資料網格
  • Propertygrid 屬性網格
  • Tree
  • Treegrid 樹形網格

 

 

 

執行過程:

頁面控制:通過在div等標籤上加特定的屬性,引入easyUI js後,通過js進行相應的處理。或渲染,或者進行資料判斷等等。

資料控制:頁面通過ajax提交,在controller中準備資料,形成json串格式,返回頁面,EasyUI拿到資料json串,利用自身提供的js函式來渲染EasyUI元件。

引入js支援:

<link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>

 

 

佈局layout

<body class="easyui-layout">
	<div data-options="region:'west',title:'選單',split:true" style="width:180px;"></div>
	<div data-options="region:'center',title:''"></div>

</body>

 

 

選單menu

ul和li組合形成多級結構

<ul id="menu" class="easyui-tree">
	<li>
		<span>第一級選單</span>
		<ul>
			<li data-options="attributes:{'url':'/page/item-add'}">新增商品</li>
		</ul>
	</li>
</ul>

 

 

頁夾Tabs

點選自動建立一個新頁夾,頁夾之間可以隨意切換

    <div id="tabs" class="easyui-tabs">
	    <div title="首頁" style="padding:20px;">
	        	
	    </div>
	</div>

注意:iframe。如果多個表格控制元件時,它們的值POST發生衝突。引數同名。修改成不同名稱。

 

 

彈出視窗Window

$("<div>").css({padding:"5px"}).html("<ul>")
.window().window('open');

$(this).window("destroy");

點選自動建立一個新頁夾,頁夾之間可以隨意切換。

 

 

樹形元件Tree

$("ul",_win).tree({(url:ajax訪問連結)

 

 

連結按鈕

<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>

 

 

提示框

$.messager.alert('提示','表單還未填寫完成!');

 

 

頁面校驗

頁面加了校驗EasyUI(在表單的元素上增加屬性,提交時,被js方法攔截,按特殊的屬性進行校驗,校驗通過繼續提交到後臺,如果校驗失敗,在對應的元素後面增加錯誤提示。)

例如:商品資訊的校驗

標題

class="easyui-textbox"  data-options="required:true" 必填

賣點

class="easyui-textbox" data-options="multiline:true,validType:'length[0,150]'"

價格

class="easyui-numberbox" data-options="min:1,max:99999999,precision:2,required:true"

庫存數量

class="easyui-numberbox" data-options="min:1,max:99999999,precision:0,required:true"

條形碼

class="easyui-textbox"  data-options="validType:'length[1,30]'"

提交

class="easyui-linkbutton" onclick="submitForm()"

 

 

 

實現商品分類樹功能

 

 

拷貝後臺資源
連結:https://pan.baidu.com/s/1w1YzPedd_s9m-_WzqKpDpA 
提取碼:9d1l 

連結:https://pan.baidu.com/s/1GEQZwqYzGG97vsxwdxBSUg 
提取碼:72s1 

 

 

表設計


 

 

 

EasyUI非同步載入樹要求

  1. id: 節點id,它是重要的來載入遠端資料
  2. text: 節點文字來顯示
  3. state: 節點狀態,“open”或“closed”,預設是“open”。當設定為“closed”,節點有子節點,並將負載從遠端站點

需要POJO物件增加兩個屬性,以滿足返回的json格式要求

 // 擴充套件get方法,滿足EasyUI的tree格式
    public String getText() {
        return getName();
    }

    public String getState() {
        return getIsParent() ? "closed" : "open";
    }

 

 

 

EasyUI非同步載入樹工作原理

使用者建立一個空的樹,然後指定一個伺服器端動態返回JSON資料用來填充樹與非同步和需求。子節點載入依賴父節點狀態。當擴充套件一個封閉的節點,如果節點沒有子節點載入,它將傳送節點id的值作為http請求引數命名為“id”到伺服器上面定義通過URL檢索的子節點。

 

 

商品分類樹載入執行過程

使用者點選EasyUI的selectItemCat按鈕,呼叫頁面載入時的jQuery的KindEditorUtil.init()方法,KindEditorUtil為在common.js中定義的js物件。在init方法中呼叫this.initItemCat(data)。Each遍歷找到selectItemCat元素,給其繫結onclick事件,onclick事件中建立window視窗,在視窗的ul上載入EasyUITree。非同步post提交,通過url(/item/cat/list)指定呼叫路徑,通過註解找到ItemCatController,執行它的queryList方法,controller中呼叫service層,執行ItemCatService的queryListById方法,service中呼叫mybatis的mapper介面,呼叫 queryListById方法,其執行ItemCatMapper.xml檔案中配置的queryListById。執行SQL語句。查詢後返回ItemCat物件集合,並由springmvc的註解@ResponseBody將java物件轉換為json串,最終返回給js,EasyUI解析並顯示樹形結構。

 

 

開發步驟

EasyUI.tree樹為非同步載入,點開樹枝,才顯示下級節點。將傳遞引數,父節點的id,預設第一次頁面傳值為0。


第一步:在item-add.jsp頁面中呼叫js事件。
 

<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>

在a標籤上的class屬性中,綁定了easyui的按鈕,設定class名稱為selectItemCat,在js中將利用這個class來繫結onclick事件。隱藏域用來返回使用者選擇樹節點的值。

第二步:呼叫common.js中的initItemCat

……
    initItemCat : function(data){
    	$(".selectItemCat").each(function(i,e){//i= index 下標,e:element:元素
    		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;  //this就指向當前的window
    			    	$("ul",_win).tree({
    			    		url:'/item/cat/list',
    			    		animate:true,
    			    		onClick : function(node){
								//只有當是葉子節點時,才進行處理
    			    			if($(this).tree("isLeaf",node.target)){
    			    				// 填寫到cid中
//_ele.parent,在當前元素的父物件,目的縮小查詢範圍			    				_ele.parent().find("[name=cid]").val(node.id);
//find(“[name=cid]”)通過jQuery的選擇器,通過一個屬性進行選擇name=cid的 
//元素後面,加上選擇節點的文字。
 			_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');
		});
    	});
    },
……

第三步:pojo

建立ItemCat pojo繼承BasePojo;增加getText方法,為easy準備。

package com.jt.manage.pojo;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_item_cat")
public class ItemCat extends BasePojo{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    // 主鍵自增長策略
    private Long id;

    // 父類目ID=0時,代表的是一級的類目
    @Column(name = "parent_id")
    private Long parentId;

    private String name;

    // 狀態。可選值:1(正常),2(刪除)
    private Integer status;

    // 排列序號,表示同級類目的展現次序,如數值相等則按名稱次序排列。取值範圍:大於零的整數
    @Column(name = "sort_order")
    private Integer sortOrder;

    // 該類目是否為父類目,1為true,0為false
    @Column(name = "is_parent")
    private Boolean isParent;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getParentId() {
        return parentId;
    }
public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Integer getSortOrder() {
        return sortOrder;
    }

    public void setSortOrder(Integer sortOrder) {
        this.sortOrder = sortOrder;
    }

    public Boolean getIsParent() {
        return isParent;
    }

    public void setIsParent(Boolean isParent) {
        this.isParent = isParent;
    }

    // 擴充套件get方法,滿足EasyUI的tree格式
    public String getText() {
        return getName();
    }

    public String getState() {
        return getIsParent() ? "closed" : "open";
    }

第四步:controller層

package com.jt.manage.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jt.manage.pojo.ItemCat;
import com.jt.manage.service.ItemCatService;

/**
 * 商品類目相關的業務邏輯處理
 *
 */
@RequestMapping("/item/cat")
@Controller
public class ItemCatController {
	@Autowired
	private ItemCatService itemCatService;
	
	@RequestMapping("list")
	@ResponseBody
	public List<ItemCat> queryList(@RequestParam(value="id", defaultValue="0") Long id){
		return this.itemCatService.queryListById(id);
	}
}

第五步:service層

package com.jt.manage.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jt.manage.mapper.ItemCatMapper;
import com.jt.manage.pojo.ItemCat;

@Service
public class ItemCatService extends BaseService<ItemCat> {

	@Autowired
	private ItemCatMapper itemCatMapper;

    public List<ItemCat> queryListById(Long id) {
        return this.itemCatMapper.queryListById(id);
    }
}

第六步:interface介面

package com.jt.manage.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.jt.manage.mapper.base.mapper.SysMapper;
import com.jt.manage.pojo.ItemCat;

public interface ItemCatMapper extends SysMapper<ItemCat>{

    /**
     * 根據ID查詢商品分類資料,parentId = id(引數)
     * 
     * @param id
     * @return
     */
    List<ItemCat> queryListById(@Param("id") Long id);

}

第七步:mapper對映檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.manage.mapper.ItemCatMapper">
	<select id="queryItemCat" parameterType="long" resultType="ItemCat">
		SELECT * FROM tb_item_cat WHERE STATUS=1 AND parent_id=#{id}
 			ORDER BY parent_id,sort_order 
	</select>
</mapper>

 

 

彈出視窗的呼叫過程

 

 

常見問題

 

 

trycatch能否寫在service層?

service層受spring的事務保護,如果在service層進行trycatch將破壞spring的回滾機制,造成無法回滾。因為spring看到有try,認定客戶要自己處理,所以不再執行回滾操作。因此需要try時,應該寫在controller層。

 

 

將json轉換List<ItemCat>時報錯

錯誤資訊:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "state" (class com.jt.manage.pojo.ItemCat), not marked as ignorable (8 known properties: "sortOrder", "status", "isParent", "parentId", "created", "updated", "name", "id"])
 at [Source: N/A; line: -1, column: -1] (through reference chain: java.util.ArrayList[0]->com.jt.manage.pojo.ItemCat["state"])