学习淘淘商城第二十七课(内容管理)
2017-04-17 20:33
197 查看
上节课我们一起学习了内容分类管理,包括增加、修改、删除等操作。这节课我们一起学习下内容管理。
第一部分:查询内容列表
首先,我们先来看看内容管理后台页面,如下图所示,可以看到页面分两部分,分为左侧内容分类和右侧内容列表两个部分。
![](http://img.blog.csdn.net/20170417195225130?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
为什么内容管理页面左侧的内容分类树形列表直接就是好的呢?我们看看代码就知道了,我们访问的入口是index.jsp页面,这个页面有"内容管理"模块,当我们点击内容管理时,就会去请求content.jsp页面。
![](http://img.blog.csdn.net/20170417195628724?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
我们看看content.jsp页面代码,如下图所示,可以看到上面那个div就是展示我们的内容分类列表的,发起的请求跟我们上节课所说的请求完全一样,因此这里不用我们做任何处理就已经可以使用了。下面的div就是页面的右部分,用来显示内容列表,页面加载的时候,会发起url:'/content/query/list',queryParams:{categoryId:0}这样的请求,这个内请求会去查询所有内容分类下的所有内容。内容列表的展示其实跟商品列表的展示及其相似,大家可以参考http://blog.csdn.net/u012453843/article/details/67644458这篇博客进行学习。不同的地方是内容列表要根据左边树形节点的Id的变化而变化。
![](http://img.blog.csdn.net/20170417200035058?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
那么内容列表是如何跟左边的内容分类联系起来的呢?我们看下面的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。
![](http://img.blog.csdn.net/20170417200936702?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
搞清了内容列表的展示原理后,我们现在就实现内容列表的展示功能
首先在taotao-content-interface工程新增一个接口类ContentService,在接口类中添加一个获取内容列表的接口(EasyUIDataGridResult getContentList(long categoryId,int page,int rows);),如下图所示。
![](http://img.blog.csdn.net/20170418211032524?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
接着在taotao-content-service工程新建一个内容实现类ContentServiceImpl,并在该实现类中实现获取内容列表接口,如下图所示。
![](http://img.blog.csdn.net/20170418211415433?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
实现类代码如下:
![](http://img.blog.csdn.net/20170418211705496?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
Controller层代码如下:
![](http://img.blog.csdn.net/20170418212149768?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
taotao-content-service工程的applicationContext-service.xml的代码如下:
![](http://img.blog.csdn.net/20170418212335911?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
springmvc.xml文件的内容如下:
![](http://img.blog.csdn.net/20170418212638407?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第二部分:添加内容
我们还是从页面代码说起,添加内容是在content.jsp当中定义的,我们可以看到内容列表有"toolbar:contentListToolbar"这么一句代码,这句代码的意思是定义了工具栏,工具栏中有多个功能。
![](http://img.blog.csdn.net/20170418214526995?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
我们来看看工具栏代码,里面有新增、编辑、删除三个操作,我们先看新增内容,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页面。
[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');的意思是将刚才表单中输入的内容清空。
![](http://img.blog.csdn.net/20170418220200791?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
分析了代码,下面我们来实现添加内容功能
首先是在ContentService接口类添加一个接口TaotaoResult addContent(TbContent content);
接着我们到ContentServiceImpl中去实现这个接口,如下图所示。
![](http://img.blog.csdn.net/20170418230428330?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
点击"提交"之后,我们便发现在小广告这个分类下的内容列表中便有了我们刚才添加的内容,如下图所示。
![](http://img.blog.csdn.net/20170418230457815?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第三部分:修改和删除内容
从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()里面的内容都是初始化编辑界面的数据。
我们再看看TT.createWindow,如下所示。这段js有个问题就是会让上面的TT.createWindow执行两遍,因此我们需要修改下上面TT.createWindow这段代码。
List<TbContent> list = contentMapper.selectByExample(example);这段代码去查找端倪,既然是调用的selectByExample这个方法,我们便去Mybatis的contentMapper.xml文件当中去看下sql语句。如下所示,可以看到要查询的字段在Base_Column_List当中。
在taotao-content-interface当中添加//获取单个内容信息TaotaoResult getContent(long id);这么一个接口,在taotao-content-service当中添加这个接口的实现,如下所示。
然后我们看下content-edit.jsp页面,表格中的字段与数据库中Tbcontent表是一致的,下面的js代码跟内容添加很相似,页面加载完之后初始化富文本编辑器,并且设置成单图片上传。点提交后先检查表单的内容是否合法,如果不合法则弹出警告。如果合法,那么用富文本编辑器的数据会与表单中的字段值进行同步,然后发起url为/rest/content/edit的请求,将表单中的数据序列化为key-value形式的字符串。在回调函数中判断操作是否成功,如果操作成功那么重新加载内容列表然后关闭弹出窗口。
先看接口,修改内容和删除内容如下。
接着看实现类
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工程。然后我们选择任何一个内容,点击"编辑"去查看富文本编辑框中的内容是否有值,如下图所示,发现没有问题了。
![](http://img.blog.csdn.net/20170419144628852?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjQ1Mzg0Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第一部分:查询内容列表
首先,我们先来看看内容管理后台页面,如下图所示,可以看到页面分两部分,分为左侧内容分类和右侧内容列表两个部分。
为什么内容管理页面左侧的内容分类树形列表直接就是好的呢?我们看看代码就知道了,我们访问的入口是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工程。然后我们选择任何一个内容,点击"编辑"去查看富文本编辑框中的内容是否有值,如下图所示,发现没有问题了。
相关文章推荐
- 学习淘淘商城第二十五课(CMS内容管理系统表设计及内容工程搭建)
- 学习淘淘商城第二十六课(内容分类管理)
- IBM ECM企业内容管理解决方案——FileNet学习系列之一
- iOS学习笔记(1)— UIView 渲染和内容管理
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(7)--批准页面布局
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(7)--批准页面布局
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(6)--允许用户给Web内容排名
- 内容管理核心JCR (JSR-170) 学习笔记
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(9)--分离和重新关联页面布局
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(3)--理解页面模型
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(3)--理解页面模型
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(8)--还原页面布局的早期版本
- Sharepoint 2013企业内容管理学习笔记(一) 半自动化内容管理
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容
- 一步步学习SPD2010--第七章节--使用BCS业务连接服务(10)--管理外部内容类型
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(4)--创建页面布局
- iOS学习笔记(1)— UIView 渲染和内容管理
- 一步步学习SPD2010--第七章节--使用BCS业务连接服务(10)--管理外部内容类型
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(2)--理解SP Server2010的Web内容管理
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(5)--修改页面布局