1. 程式人生 > >學習淘淘商城第二十七課(內容管理)

學習淘淘商城第二十七課(內容管理)

      上節課我們一起學習了內容分類管理,包括增加、修改、刪除等操作。這節課我們一起學習下內容管理。

第一部分:查詢內容列表

      首先,我們先來看看內容管理後臺頁面,如下圖所示,可以看到頁面分兩部分,分為左側內容分類和右側內容列表兩個部分。


       為什麼內容管理頁面左側的內容分類樹形列表直接就是好的呢?我們看看程式碼就知道了,我們訪問的入口是index.jsp頁面,這個頁面有"內容管理"模組,當我們點選內容管理時,就會去請求content.jsp頁面。


        我們看看content.jsp頁面程式碼,如下圖所示,可以看到上面那個div就是展示我們的內容分類列表的,發起的請求跟我們上節課所說的請求完全一樣,因此這裡不用我們做任何處理就已經可以使用了。下面的div就是頁面的右部分,用來顯示內容列表,頁面載入的時候,會發起url:'/content/query/list',queryParams:{categoryId:0}這樣的請求,這個內請求會去查詢所有內容分類下的所有內容。內容列表的展示其實跟商品列表的展示及其相似,大家可以參考http://blog.csdn.net/u012453843/article/details/67644458這篇部落格進行學習。不同的地方是內容列表要根據左邊樹形節點的Id的變化而變化。


          那麼內容列表是如何跟左邊的內容分類聯絡起來的呢?我們看下面的js程式碼,如下圖所示,$(function(){});函式是在頁面載入完之後觸發執行的js程式碼,var tree = $("#contentCategoryTree");顯然是獲取內容分類樹,var datagrid = $("#contentList");是獲取內容列表,onClick : function(node){if(tree.tree("isLeaf",node.target)){datagrid.datagrid('reload', {categoryId :node.id});}}這段程式碼的意思是當我們點選左邊內容分類樹的某個節點時,會做下判斷,判斷是不是葉子節點,如果是葉子節點那麼就給categoryId賦值為這個葉子節點的id並且會重新載入內容列表,也就意味著重新發起url:'/content/query/list'請求,只是這時的引數queryParams:中categoryId的值變成了單個葉子節點的id。


        搞清了內容列表的展示原理後,我們現在就實現內容列表的展示功能

        首先在taotao-content-interface工程新增一個介面類ContentService,在介面類中新增一個獲取內容列表的介面(EasyUIDataGridResult getContentList(long categoryId,int page,int rows);),如下圖所示。


      接著在taotao-content-service工程新建一個內容實現類ContentServiceImpl,並在該實現類中實現獲取內容列表介面,如下圖所示。


       實現類程式碼如下:

package com.taotao.content.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.content.service.ContentService;
import com.taotao.mapper.TbContentMapper;
import com.taotao.pojo.TbContent;
import com.taotao.pojo.TbContentExample;
import com.taotao.pojo.TbContentExample.Criteria;

@Service
public class ContentServiceImpl implements ContentService {
	@Autowired
	private TbContentMapper contentMapper;

	@Override
	public EasyUIDataGridResult getContentList(long categoryId, int page, int rows) {
		//設定分頁資訊
		PageHelper.startPage(page, rows);
		//執行查詢
		TbContentExample example = new TbContentExample();
		Criteria createCriteria = example.createCriteria();
		createCriteria.andCategoryIdEqualTo(categoryId);
		//獲取查詢結果
		List<TbContent> list = contentMapper.selectByExample(example);
		PageInfo<TbContent> pageInfo = new PageInfo<>(list);
		EasyUIDataGridResult result = new EasyUIDataGridResult();
		result.setRows(list);
		result.setTotal(pageInfo.getTotal());
		//返回結果
		return result; 
	}

}
      下面到Controller層去呼叫服務層介面並返回結果給前臺頁面,如下圖所示。



        Controller層程式碼如下:

package com.taotao.controller;

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.ResponseBody;

import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.content.service.ContentService;

@Controller
public class ContentController {
    
	@Autowired
	private ContentService contentSerive;
	
	@RequestMapping("/content/query/list")
	@ResponseBody
	public EasyUIDataGridResult getContentList(Long categoryId,Integer page,Integer rows){
		EasyUIDataGridResult result = contentSerive.getContentList(categoryId, page, rows);
		return result;
	}
}
      這還沒完,因為我們還沒有釋出服務介面和引用介面,我們先在taotao-content-service工程釋出dubbo服務,如下圖所示。


      taotao-content-service工程的applicationContext-service.xml的程式碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
    
    <!-- 配置包掃描器,掃描所有帶@Service註解的類 -->
	<context:component-scan base-package="com.taotao.content.service"/>
	
	<!-- 釋出dubbo服務 -->
	<!-- 提供方應用資訊,用於計算依賴關係 -->
	<dubbo:application name="taotao-content" />
	<!-- 註冊中心的地址 -->
	<dubbo:registry protocol="zookeeper" address="192.168.156.14:2181" />
	<!-- 用dubbo協議在20881埠暴露服務 -->
	<dubbo:protocol name="dubbo" port="20881" />
	<!-- 宣告需要暴露的服務介面 -->
	<dubbo:service interface="com.taotao.content.service.ContentCategoryService" ref="contentCategoryServiceImpl" timeout="300000"/>
	<dubbo:service interface="com.taotao.content.service.ContentService" ref="contentServiceImpl" timeout="300000"/>
</beans>
       下面我們到taotao-manager-web後臺工程引用dubbo釋出的內容服務


      springmvc.xml檔案的內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
       
    <!-- 載入配置檔案 -->
    <context:property-placeholder location="classpath:resource/resource.properties"/>    
	<!-- 配置註解驅動 -->
	<mvc:annotation-driven />
	<!-- 檢視解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 配置包掃描器,掃描@Controller註解的類 -->
	<context:component-scan base-package="com.taotao.controller"/>
	
	<!-- 配置資源對映 -->
	<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
	<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
	
	<!-- 多媒體解析器 -->
	<!-- 配置檔案上傳解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 設定預設編碼 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 設定檔案上傳的最大值5MB,5*1024*1024 -->
		<property name="maxUploadSize" value="5242880"></property>
	</bean>
	
	<!-- 引用dubbo服務 -->
	<dubbo:application name="taotao-manager-web"/>
	<dubbo:registry protocol="zookeeper" address="192.168.156.14:2181"/>	
	<dubbo:reference interface="com.taotao.service.ItemService" id="itemService" />
	<dubbo:reference interface="com.taotao.service.ItemCatService" id="itemCatService" />
	<dubbo:reference interface="com.taotao.content.service.ContentCategoryService" id="contentCategoryService" />
	<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
</beans>
       好,現在我們開始測試,對taotao-content工程進行重新打包,然後重啟taotao-content工程和taotao-manager-web工程,重啟後我們訪問內容列表,如下圖所示,發現可以正常訪問了。


第二部分:新增內容

       我們還是從頁面程式碼說起,新增內容是在content.jsp當中定義的,我們可以看到內容列表有"toolbar:contentListToolbar"這麼一句程式碼,這句程式碼的意思是定義了工具欄,工具欄中有多個功能。

           我們來看看工具欄程式碼,裡面有新增、編輯、刪除三個操作,我們先看新增內容,text指定我們看到的圖示後面的文字,iconCls指定新增圖示,handler:function()則是當我們點選"新增"按鈕時觸發的函式,var node = $("#contentCategoryTree").tree("getSelected");的意思是得到使用者選中的內容分類節點。if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){的意思是如果沒有選中的不是節點或者該節點不是葉子節點,那麼就彈出提示"新增內容必須選擇一個內容分類!"。如果點選的是葉子節點的話,就會呼叫common.js當中定義的TT的createWindow方法初始化一個彈出框,彈出框中顯示的頁面是引數指定的url: "/content-add",也就是content-add.jsp頁面。

var contentListToolbar = [{
    text:'新增',
    iconCls:'icon-add',
    handler:function(){
    	var node = $("#contentCategoryTree").tree("getSelected");
    	if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){
    		$.messager.alert('提示','新增內容必須選擇一個內容分類!');
    		return ;
    	}
    	TT.createWindow({
			url : "/content-add"
		}); 
    }
},{
    text:'編輯',
    iconCls:'icon-edit',
    handler:function(){
    	var ids = TT.getSelectionsIds("#contentList");
    	if(ids.length == 0){
    		$.messager.alert('提示','必須選擇一個內容才能編輯!');
    		return ;
    	}
    	if(ids.indexOf(',') > 0){
    		$.messager.alert('提示','只能選擇一個內容!');
    		return ;
    	}
		TT.createWindow({
			url : "/content-edit",
			onLoad : function(){
				var data = $("#contentList").datagrid("getSelections")[0];
				$("#contentEditForm").form("load",data);
				
				// 實現圖片
				if(data.pic){
					$("#contentEditForm [name=pic]").after("<a href='"+data.pic+"' target='_blank'><img src='"+data.pic+"' width='80' height='50'/></a>");	
				}
				if(data.pic2){
					$("#contentEditForm [name=pic2]").after("<a href='"+data.pic2+"' target='_blank'><img src='"+data.pic2+"' width='80' height='50'/></a>");					
				}
				
				contentEditEditor.html(data.content);
			}
		});    	
    }
},{
    text:'刪除',
    iconCls:'icon-cancel',
    handler:function(){
    	var ids = TT.getSelectionsIds("#contentList");
    	if(ids.length == 0){
    		$.messager.alert('提示','未選中商品!');
    		return ;
    	}
    	$.messager.confirm('確認','確定刪除ID為 '+ids+' 的內容嗎?',function(r){
    	    if (r){
    	    	var params = {"ids":ids};
            	$.post("/content/delete",params, function(data){
        			if(data.status == 200){
        				$.messager.alert('提示','刪除內容成功!',undefined,function(){
        					$("#contentList").datagrid("reload");
        				});
        			}
        		});
    	    }
    	});
    }
}];
     下面我們便來看下content-add.jsp頁面,如下圖所示,表格中的欄位名稱與我們的資料庫中表的欄位是一致的,這樣我們便可以直接使用逆向工程生成的程式碼了。當頁面載入完之後,會觸發$(function()方法,contentAddEditor = TT.createEditor("#contentAddForm [name=content]");的意思是初始化一個富文字編輯器,TT.initOnePicUpload();的意思是初始化單張圖片上傳按鈕,也就是說一次只能選擇一張圖片(因為我們的pic和pic2欄位各自對應一張圖片路徑),$("#contentAddForm [name=categoryId]").val($("#contentCategoryTree").tree("getSelected").id);這行程式碼的意思是把使用者選擇的內容分類節點的id賦值給隱藏域<input type="hidden" name="categoryId"/>。這樣我們在提交表單的時候便把內容分類也一併提交了。當我們點選提交的時候便觸發submitForm : function ()方法,if(!$('#contentAddForm').form('validate')){的意思是如果表單輸入的不合法那麼會提示"表單還未填寫完!"。contentAddEditor.sync();的意思是如果表單填寫合法,那麼富文字編輯器將與表單中的隱藏域欄位進行內容同步。$.post("/content/save")的意思是發起url為/content/save的請求,$("#contentAddForm").serialize()將表單中的資料序列化為key-value形式的字串,function(data)是指回調函式。if(data.status == 200){意思是如果返回的狀態為200的話說明新增成功了,$("#contentList").datagrid("reload");意思是新增成功後,內容列表要進行重新載入。TT.closeCurrentWindow();的意思是關閉彈出視窗。clearForm : function(){是重置按鈕觸發的方法,$('#contentAddForm').form('reset');的意思是將剛才表單中輸入的內容清空。


     分析了程式碼,下面我們來實現新增內容功能

     首先是在ContentService介面類新增一個介面TaotaoResult addContent(TbContent content);

     接著我們到ContentServiceImpl中去實現這個介面,如下圖所示。

@Override
	public TaotaoResult addContent(TbContent content) {
		//補充屬性
		content.setCreated(new Date());
		content.setUpdated(new Date());
		//新增
		contentMapper.insert(content);
		//返回結果
		return TaotaoResult.ok();
	}
      由於ContentService服務我們已經在dubbo中釋出過了,而且taotao-manager-web工程也引用了,下面我們需要做的便是實現Controller層,如下所示。
@RequestMapping("/content/save")
	@ResponseBody
	public TaotaoResult addContent(TbContent content){
		TaotaoResult result = contentSerive.addContent(content);
		return result;
	}
      修改完之後,我們重新打包taotao-content工程,打包後重啟taotao-content工程和taotao-manager-web工程,然後去新增一個內容,新增介面如下圖所示。


      點選"提交"之後,我們便發現在小廣告這個分類下的內容列表中便有了我們剛才新增的內容,如下圖所示。


第三部分:修改和刪除內容

       從content.jsp頁面說起,當我們點選"編輯"按鈕後會觸發handler:function()這個方法,var ids = TT.getSelectionsIds("#contentList");的意思是獲取內容列表的所有id的集合。if(ids.length == 0){$.messager.alert('提示','必須選擇一個內容才能編輯!');return ;}的意思是如果沒有選擇任何內容便彈出警告。if(ids.indexOf(',') > 0){的意思是如果選擇的內容多於一個的話也彈出警告。TT.createWindow({的意思是初始一個彈出視窗。url : "/content-edit"的意思是在彈出框中載入的是content-edit.jsp頁面。onLoad : function()裡面的內容都是初始化編輯介面的資料。

text:'編輯',
    iconCls:'icon-edit',
    handler:function(){
    	var ids = TT.getSelectionsIds("#contentList");
    	if(ids.length == 0){
    		$.messager.alert('提示','必須選擇一個內容才能編輯!');
    		return ;
    	}
    	if(ids.indexOf(',') > 0){
    		$.messager.alert('提示','只能選擇一個內容!');
    		return ;
    	}
		TT.createWindow({
			url : "/content-edit",
			onLoad : function(){
				var data = $("#contentList").datagrid("getSelections")[0];
				$("#contentEditForm").form("load",data);
				
				// 實現圖片
				if(data.pic){
					$("#contentEditForm [name=pic]").after("<a href='"+data.pic+"' target='_blank'><img src='"+data.pic+"' width='80' height='50'/></a>");	
				}
				if(data.pic2){
					$("#contentEditForm [name=pic2]").after("<a href='"+data.pic2+"' target='_blank'><img src='"+data.pic2+"' width='80' height='50'/></a>");					
				}
				
				contentEditEditor.html(data.content);
			}
		});    	

        我們再看看TT.createWindow,如下所示。這段js有個問題就是會讓上面的TT.createWindow執行兩遍,因此我們需要修改下上面TT.createWindow這段程式碼。

createWindow : function(params){
    	$("<div>").css({padding:"5px"}).window({
    		width : params.width?params.width:"80%",
    		height : params.height?params.height:"80%",
    		modal:true,
    		title : params.title?params.title:" ",
    		href : params.url,
		    onClose : function(){
		    	$(this).window("destroy");
		    },
		    onLoad : function(){
		    	if(params.onLoad){
		    		params.onLoad.call(this);
		    	}
		    }
    	}).window("open");
    },
       修改後的內如如下,使用了一個臨時變數來記錄呼叫次數,如果是第二次呼叫的話,則直接返回,不做下面的操作。另外修改的地方是新增一個get請求,根據ID去查詢這條內容的全部資訊。
var number = 0;
		TT.createWindow({
			url : "/content-edit",
			onLoad : function(){
			    number = number +1;
			    if(number == 2){
			    	return;
			    }
				var node = $("#contentList").datagrid("getSelections")[0];
				var params = {"id":node.id};
				$.get("/content/getContent",params, function(data){
        			if(data.status == 200){
        				debugger
        				node = data.data;
        				$("#contentEditForm").form("load",node);
        				
        				// 實現圖片
        				if(node.pic){
        					$("#contentEditForm [name=pic]").after("<a href='"+node.pic+"' target='_blank'><img src='"+node.pic+"' width='80' height='50'/></a>");	
        				}
        				if(node.pic2){
        					$("#contentEditForm [name=pic2]").after("<a href='"+node.pic2+"' target='_blank'><img src='"+node.pic2+"' width='80' height='50'/></a>");					
        				}
        				
        				contentEditEditor.html(node.content);
        			}
        		});
			}
		});    	
        那麼為何var node = $("#contentList").datagrid("getSelections")[0];這句程式碼就獲取到了內容物件還要再通過id去獲取內容物件呢?這是因為列表查詢的時候就沒有查詢content欄位,也就是富文字編輯框中的內容,我們可以點選編輯,就會發現富文字編輯框是空的,並沒有我們新增內容時新增的內容。其實我們可以從獲取列表的實現介面中

List<TbContent> list = contentMapper.selectByExample(example);這段程式碼去查詢端倪,既然是呼叫的selectByExample這個方法,我們便去Mybatis的contentMapper.xml檔案當中去看下sql語句。如下所示,可以看到要查詢的欄位在Base_Column_List當中。

 <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.taotao.pojo.TbContentExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from tb_content
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>
        我們再看看Base_Column_List當中的欄位,發現並沒有content欄位,這麼做的好處是我們在查詢內容列表的時候由於並不需要顯示內容,而內容可能是非常龐大的,如果把內容欄位也一併查詢出來的話,那麼必定是很消耗效能。因此預設採取了不查詢內容欄位的方式進行查詢。
<sql id="Base_Column_List" >
    id, category_id, title, sub_title, title_desc, url, pic, pic2, created, updated
  </sql>
        內容欄位所在的集合是Blob_Column_List,如下所示。
<sql id="Blob_Column_List" >
    content
  </sql>
        我們最好是在要查詢某一條內容的時候再去查詢content這個欄位,而我們的selectByPrimaryKey方法便查詢了包括content欄位在內的所有欄位的內容。如下所示。
<select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Long" >
    select 
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from tb_content
    where id = #{id,jdbcType=BIGINT}
  </select>
       也就是說,我們預設的內容列表中的每條記錄都是沒有content這個欄位的內容的,因此我們需要在使用者點選編輯按鈕的時候根據內容ID去查詢這個內容的所有資訊,這也是為何在TT.createWindow當中新增$.get("/content/getContent",params, function(data){這麼一個請求的原因。
       在taotao-content-interface當中新增//獲取單個內容資訊TaotaoResult getContent(long id);這麼一個介面,在taotao-content-service當中新增這個介面的實現,如下所示。
@Override
	public TaotaoResult getContent(long id) {
		TbContent content = contentMapper.selectByPrimaryKey(id);
		return TaotaoResult.ok(content);
	}
        接著就是到taotao-manager-web工程新增暴露的介面,如下所示。
@RequestMapping("/content/getContent")
	@ResponseBody
	public TaotaoResult getContent(Long id){
		TaotaoResult result = contentSerive.getContent(id);
		return result;
	}

        然後我們看下content-edit.jsp頁面,表格中的欄位與資料庫中Tbcontent表是一致的,下面的js程式碼跟內容新增很相似,頁面載入完之後初始化富文字編輯器,並且設定成單圖片上傳。點提交後先檢查表單的內容是否合法,如果不合法則彈出警告。如果合法,那麼用富文字編輯器的資料會與表單中的欄位值進行同步,然後發起url為/rest/content/edit的請求,將表單中的資料序列化為key-value形式的字串。在回撥函式中判斷操作是否成功,如果操作成功那麼重新載入內容列表然後關閉彈出視窗。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<div style="padding:10px 10px 10px 10px">
	<form id="contentEditForm" class="itemForm" method="post">
		<input type="hidden" name="categoryId"/>
		<input type="hidden" name="id"/>
	    <table cellpadding="5">
	        <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" type="text" name="subTitle" style="width: 280px;"></input></td>
	        </tr>
	        <tr>
	            <td>內容描述:</td>
	            <td><input class="easyui-textbox" name="titleDesc" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;"></input>
	            </td>
	        </tr>
	         <tr>
	            <td>URL:</td>
	            <td><input class="easyui-textbox" type="text" name="url" style="width: 280px;"></input></td>
	        </tr>
	        <tr>
	            <td>圖片:</td>
	            <td>
	                <input type="hidden" name="pic" />
	                <a href="javascript:void(0)" class="easyui-linkbutton onePicUpload">圖片上傳</a>
	            </td>
	        </tr>
	        <tr>
	            <td>圖片2:</td>
	            <td>
	            	<input type="hidden" name="pic2" />
	            	<a href="javascript:void(0)" class="easyui-linkbutton onePicUpload">圖片上傳</a>
	            </td>
	        </tr>
	        <tr>
	            <td>內容:</td>
	            <td>
	                <textarea style="width:800px;height:300px;visibility:hidden;" name="content"></textarea>
	            </td>
	        </tr>
	    </table>
	</form>
	<div style="padding:5px">
	    <a href="javascript:void(0)" class="easyui-linkbutton" onclick="contentEditPage.submitForm()">提交</a>
	    <a href="javascript:void(0)" class="easyui-linkbutton" onclick="contentEditPage.clearForm()">重置</a>
	</div>
</div>
<script type="text/javascript">
var contentEditEditor ;
$(function(){
	contentEditEditor = TT.createEditor("#contentEditForm [name=content]");
	TT.initOnePicUpload();
});

var contentEditPage = {
		submitForm : function(){
			if(!$('#contentEditForm').form('validate')){
				$.messager.alert('提示','表單還未填寫完成!');
				return ;
			}
			contentEditEditor.sync();
			
			$.post("/rest/content/edit",$("#contentEditForm").serialize(), function(data){
				if(data.status == 200){
					$.messager.alert('提示','修改內容成功!');
					$("#contentList").datagrid("reload");
					TT.closeCurrentWindow();
				}
			});
		},
		clearForm : function(){
			
		}
};

</script>
     至於刪除的js就更容易理解了,這裡就不囉嗦了。現在我們開始寫修改和刪除內容功能。

     先看介面,修改內容和刪除內容如下。

package com.taotao.content.service;

import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.pojo.TbContent;

public interface ContentService {
	//獲取內容列表
	EasyUIDataGridResult getContentList(long categoryId,int page,int rows);
	//新增內容
	TaotaoResult addContent(TbContent content);
	//修改內容
	TaotaoResult updateContent(TbContent content);
	//刪除內容
	TaotaoResult deleteContent(String ids);
	//獲取單個內容資訊
	TaotaoResult getContent(long id);
}
      接著看實現類
package com.taotao.content.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.content.service.ContentService;
import com.taotao.mapper.TbContentMapper;
import com.taotao.pojo.TbContent;
import com.taotao.pojo.TbContentExample;
import com.taotao.pojo.TbContentExample.Criteria;

@Service
public class ContentServiceImpl implements ContentService {
	@Autowired
	private TbContentMapper contentMapper;

	@Override
	public EasyUIDataGridResult getContentList(long categoryId, int page, int rows) {
		//設定分頁資訊
		PageHelper.startPage(page, rows);
		//執行查詢
		TbContentExample example = new TbContentExample();
		Criteria createCriteria = example.createCriteria();
		createCriteria.andCategoryIdEqualTo(categoryId);
		//獲取查詢結果
		List<TbContent> list = contentMapper.selectByExample(example);
		PageInfo<TbContent> pageInfo = new PageInfo<>(list);
		EasyUIDataGridResult result = new EasyUIDataGridResult();
		result.setRows(list);
		result.setTotal(pageInfo.getTotal());
		//返回結果
		return result; 
	}

	@Override
	public TaotaoResult addContent(TbContent content) {
		//補充屬性
		content.setCreated(new Date());
		content.setUpdated(new Date());
		//新增
		contentMapper.insert(content);
		//返回結果
		return TaotaoResult.ok();
	}

	@Override
	public TaotaoResult updateContent(TbContent content) {
		// 填充屬性
		content.setUpdated(new Date());
		//更新內容
		contentMapper.updateByPrimaryKey(content);
		//返回結果
		return TaotaoResult.ok();
	}

	@Override
	public TaotaoResult deleteContent(String ids) {
		String[] idList = ids.split(",");
		for(String id : idList){
			//刪除內容
			contentMapper.deleteByPrimaryKey(Long.valueOf(id));
		}
		//返回結果
		return TaotaoResult.ok();
	}

	@Override
	public TaotaoResult getContent(long id) {
		TbContent content = contentMapper.selectByPrimaryKey(id);
		return TaotaoResult.ok(content);
	}

}
       下面我們再看下Controller層
package com.taotao.controller;

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.ResponseBody;

import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.content.service.ContentService;
import com.taotao.pojo.TbContent;

@Controller
public class ContentController {
    
	@Autowired
	private ContentService contentSerive;
	
	@RequestMapping("/content/query/list")
	@ResponseBody
	public EasyUIDataGridResult getContentList(Long categoryId,Integer page,Integer rows){
		EasyUIDataGridResult result = contentSerive.getContentList(categoryId, page, rows);
		return result;
	}
	
	@RequestMapping("/content/save")
	@ResponseBody
	public TaotaoResult addContent(TbContent content){
		TaotaoResult result = contentSerive.addContent(content);
		return result;
	}
	
	@RequestMapping("/rest/content/edit")
	@ResponseBody
	public TaotaoResult updateContent(TbContent content){
		TaotaoResult result = contentSerive.updateContent(content);
		return result;
	}
	
	@RequestMapping("/content/delete")
	@ResponseBody
	public TaotaoResult deleteContent(String ids){
		TaotaoResult result = contentSerive.deleteContent(ids);
		return result;
	}
	
	@RequestMapping("/content/getContent")
	@ResponseBody
	public TaotaoResult getContent(Long id){
		TaotaoResult result = contentSerive.getContent(id);
		return result;
	}
}
      做好以上工作後,我們重新打包taotao-content工程,然後重啟taotao-content和taotao-manager-web工程。然後我們選擇任何一個內容,點選"編輯"去檢視富文字編輯框中的內容是否有值,如下圖所示,發現沒有問題了。




相關推薦

學習商城第二內容管理

      上節課我們一起學習了內容分類管理,包括增加、修改、刪除等操作。這節課我們一起學習下內容管理。 第一部分:查詢內容列表       首先,我們先來看看內容管理後臺頁面,如下圖所示,可以看到頁面分兩部分,分為左側內容分類和右側內容列表兩個部分。        為什

學習商城商品列表展示、PageHelper的使用

        上節課我們實現了展示後臺頁面的功能,如下圖所示。可以看到,目前頁面是沒有資料的,我們本節課便一起學習下如何展示商品列表。           我們知道,EasyUI的最大特點便是區域性重新整理,所有展示都是分模組展示的,不像我們一般頁面採用全部重新整理。查

學習商城第二KindEditor富文字編輯器的使用

      上節課我們一起學習了怎樣解決KindEditor富文字編輯器上傳圖片的瀏覽器相容性問題,這節課我們一起學習下富文字編輯器與淘淘商城相結合的使用方法。       我們在發表一篇部落格或者微博的時候,都會用到富文字編輯器,因為它提供的功能非常豐富,不僅能寫文字,還

學習商城第九商品詳情頁面對加入購物車進行改造

        我們訪問淘淘商城首頁(前提是啟動了所有的服務及工程,雖然有個別工程用不上,不過也沒關係),在搜尋框中輸入要搜尋的商品,我以前新增過"金立M2017"這款手機,我就搜尋它。          搜尋到的結果頁面如下圖所示。           我們再點選這款

商城(展示後臺管理頁面)

前面做了那麼多鋪墊,現在我們開始著手處理後臺管理系統。        首先,大家需要下載淘淘商城的靜態資原始檔,大家可以到:https://download.csdn.net/download/anaitudou/10505519這個地址進行下載,下載後解壓,解壓後可以看到有

Spring入門第二

url cati urn ksh base stock XML repo study 聲明式事務 直接上代碼: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.j

python學習第二HTML之表單標籤

form表單標籤 表單用於向伺服器傳輸資料。 表單能夠包含 input 元素,比如文字欄位、複選框、單選框、提交按鈕等等。 表單還可以包含textarea、select、fieldset和 label 元素。 表單屬性 HTML 表單用於接收不同型別的使用者輸入,使用

C++筆記 第二 二階構造模式---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。 學習C++編譯環境:Linux 第二十七課 二階構造模式 1.建構函式的回顧 關於建構函式 類的建構函式用於物件的初始化 建構函式與類同名並且沒有返回值 建構函式在物件定義時自動被呼叫 2.問題 1

走入計算機的第二模塊與包的調用

項目 conf form 第一時間 生產環境 兩個 nag 不同 spec 一 模塊(module)的概念 在計算機程序的開發過程中,隨著程序代碼越寫越多,在一個文件裏代碼就會越來越長,越來越不容易維護。 為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件裏,每個

python 學習第二五天協程

協程 協程,又稱微執行緒,纖程。英文名Coroutine。 優點1: 協程極高的執行效率。因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯。 優點2: 不需要多執行緒的鎖機制,因為只有一個執行緒,

python 學習第二二天threading模組

啟動一個執行緒 import threading import time def he(num): #定義每個執行緒要執行的函式 print("running on number:%s" %num) time.sleep(3) if __name

LeetCode刷題記錄——第二移除元素

27.移除元素 題目描述 思路 程式碼實現 題目描述 給定一個數組 nums 和一個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後陣列的新長度。 不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 O(

LeetCode刷題記錄——第二八題實現strStr()

28.實現strStr() 題目描述 程式碼實現 題目描述 實現 strStr() 函式。 給定一個 haystack 字串和一個 needle 字串,在 haystack 字串中找出 needle 字串出現的第一個位置 (從0開始)

LeetCode題庫第二六題簡單系列

簡單系列的第二十一題對於Python有序連結暫時沒有弄明白是怎麼操作的,只是看了別人大神的程式碼過了,所以暫時不寫。 現在由二十六題開始繼續做題。 題目: 給定一個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。 不要使用額外

學習商城第九購物車實現分析及工程搭建

        關於購物車模組,京東和淘寶並不一樣,京東允許使用者在沒有登入的情況下就使用購物車,而且加到購物車裡面的商品可以一直儲存著(其實是放到了Cookie當中,如果清空了Cookie也就清空購物車了)。而淘寶則是必須先登入才能將商品新增到購物車當中,就使用者體驗來說

學習商城第八單點登入之通過token獲取使用者資訊

        首先還是看介面文件關於通過token獲取使用者資訊的說明,如下圖所示。             看了說明文件我們便知道該怎麼做了,在taotao-sso-interface工程的UserService介面類中新增一個介面,如下圖所示。          

學習商城第六商品詳情快取的實現

       上節課我們一起分析了下商品詳情快取策略,這節課我們一起實現商品詳情快取的新增。        首先,我們要想清楚快取應該加到哪個工程當中,現在我們有兩個工程可以選擇,第一個工程是taotao-item-web(商品詳情工程),如果把快取加到這個工程的話,由於該

學習商城第四首頁跳轉到搜尋頁面及搜尋實現分析

       上節課我們一起學習了將資料從資料庫匯入到索引庫,這節課我們一起學習下首頁跳轉到搜尋頁面。        我們要訪問taotao-portal-web工程就要先啟動redis服務(大家根據自己使用的情況啟動,使用的是單機版就啟動單機版伺服器,使用的是叢集就啟動叢

學習商城第五為何引入ActiveMQ

        我們在學習Solr索引的時候,每當新增一個商品後,都要把資料庫中的資料全部重新匯入到索引庫,特別消耗效能和時間,這顯然是我們所不能忍受的,這就需要優化我們的方案。最好是在商品新增的時候就單獨將該商品同步到索引庫,這樣便簡單快捷地實現了資料庫與索引庫的同步。

學習商城SSM框架整合之逆向工程

         上節課我們一起學習了使用SVN來上傳和下載程式碼,這節課我們一起學習SSM框架整合。          SSM代表Spring+SpringMVC+Mybatis,我們先來使用Mybatis生成逆向工程。          首先我們需要安裝mysql5.5