首页 > 代码库 > 【项目总结:波士顿东大校友会】CMS栏目个性化设置

【项目总结:波士顿东大校友会】CMS栏目个性化设置

开发流程完整实现:

1、实体(entity、model)

(截取代码省略setter、getter)

/**
 * 类描述:系统栏目实体   
 * 创建人:周磊 
 * 创建时间:2013-8-30 下午03:58:50   
 */
public class ChannelEntity {
	/**
	 * 初始化信息
	 */
	public static final String ROOT_NAME = "网站系统栏目";
	public static final int ROOT_ID = 0;
	
	/**
	 *栏目类型
	 */
	public enum ChannelType {
//		NAV_CHANNEL("顶部导航栏目"),
		TOPIC_LIST("文章列表栏目"),
		TOPIC_CONTENT("文章内容栏目"),TOPIC_IMG("图片列表栏目");
		
		private String value;
		
		private ChannelType(String value) {
			this.value = http://www.mamicode.com/value;>
二、Mapper(DAO)

使用MyBatis,通过sql映射实现基本增删改查

接口:

package org.boston.seuaa.mapper;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.boston.seuaa.dto.ChannelTree;
import org.boston.seuaa.entity.ChannelEntity;

/**
 * 类描述: 栏目映射接口
 * 创建人:周磊 
 * 创建时间:2013-9-10 下午02:00:45   
 */
public interface ChannelMapper {

	public void insert(ChannelEntity channel)throws SQLException;
	
	public void deleteById(Integer[] ids)throws SQLException;
	
	public void update(ChannelEntity channel) throws SQLException;
	
	public ChannelEntity queryById(Integer id) throws SQLException;
	
	public Long queryCount(Map<String, Object> map) throws SQLException;
	
	public List<ChannelEntity> queryList(Map<String , Object> map) throws SQLException;
	
	public List<ChannelTree> queryTree(Map<String , Object> map) throws SQLException;
	
}
	
	

映射文件(SQL逻辑):

<?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="org.boston.seuaa.mapper.ChannelMapper">

	<insert id="insert" parameterType="org.boston.seuaa.entity.ChannelEntity"
		useGeneratedKeys="true" keyProperty="id">
	 <![CDATA[
		insert into	t_channel
		(name,parentId,customLink,customLinkUrl,type,isIndex,isTopNav,status,orders,createDate)
		values
		(#{name},#{parentId},#{type},#{isIndex},#{isTopNav},#{status},#{orders},#{createDate})
		]]>
	</insert>

	<update id="update" parameterType="org.boston.seuaa.entity.ChannelEntity">
	 <![CDATA[
		update t_channel set
		name=#{name},type=#{type},isTopNav=#{isTopNav},status=#{status},isIndex=#{isIndex}
		where id=#{id}
	]]>
		
 	</update>

	<delete id="deleteById">
		delete from t_channel where 1=1 and id in
		<foreach collection="array" index="index" item="item" open="("
			separator="," close=")">
			#{item}
	    </foreach>
	</delete>
	
	<select id="queryById" parameterType="int"
		resultType="org.boston.seuaa.entity.ChannelEntity">
		select *
		from t_channel where id=#{id}
 	</select>

	<select id="queryCount" resultType="java.lang.Long">
		select count(*) from
		t_channel t where 1=1
	</select>
	
	<select id="queryList" parameterType="java.util.Map" resultType="org.boston.seuaa.entity.ChannelEntity">
		select *
		from t_channel
		<where>
			<if test="parentId!=null">parentId=#{parentId}</if>
		</where>		
		order by createDate desc
		<if test="pagesize!=null and minnum!=null">limit #{minnum},#{pagesize}</if>
	</select>
	
	<select id="queryTree" parameterType="int" resultType="org.boston.seuaa.dto.ChannelTree">
		select id,name,parentId
		from t_channel
		where 1=1 
		<if test="parentId!=null and parentId!=''">and parentId = #{parentId}</if>
	</select>
	

</mapper>

三、Service

Service接口

package org.boston.seuaa.service;

import java.util.List;

import org.boston.seuaa.dto.ChannelTree;
import org.boston.seuaa.entity.ChannelEntity;
import org.boston.seuaa.utils.Pagination;
import org.boston.seuaa.utils.ResultList;
import org.boston.seuaa.utils.ServiceException;

public interface ChannelService {
	public void insertChannel(ChannelEntity user)throws ServiceException;
	
	public void deleteChannel(Integer id) throws ServiceException;
	
	public void deleteChannel(Integer[] ids) throws ServiceException;
	
	public void updateChannel(ChannelEntity channel)throws ServiceException;
	
	public ChannelEntity queryChannelById(Integer id) throws ServiceException;
	
	public ResultList<ChannelEntity> queryChannelList(Integer parentId, Pagination page)throws ServiceException;
	
	public List<ChannelTree> queryChannelTree(Integer parentId) throws ServiceException;
	
}

Service实现:

package org.boston.seuaa.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.boston.seuaa.dto.ChannelTree;
import org.boston.seuaa.entity.ChannelEntity;
import org.boston.seuaa.mapper.ChannelMapper;
import org.boston.seuaa.utils.Pagination;
import org.boston.seuaa.utils.ResultList;
import org.boston.seuaa.utils.ResultListImpl;
import org.boston.seuaa.utils.ServiceException;
import org.boston.seuaa.utils.WqLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class ChannelServiceImpl implements ChannelService {

	@Autowired
	private ChannelMapper channelMapper;
	
	public void deleteChannel(Integer id) throws ServiceException {
		
		Integer[] ids = new Integer[]{id};
		try {
			channelMapper.deleteById(ids);
		} catch (SQLException e) {
			WqLogger.error("删除用户错误", e, this.getClass());
			throw new ServiceException("删除错误", e);
		}
		
	}

	public void deleteChannel(Integer[] ids) throws ServiceException {
		try {
			channelMapper.deleteById(ids);
		} catch (SQLException e) {
			WqLogger.error("删除用户错误", e, this.getClass());
			throw new ServiceException("删除错误", e);
		}
	}

	public void insertChannel(ChannelEntity channel) throws ServiceException{
		try {
			channelMapper.insert(channel);
		} catch (SQLException e) {
			WqLogger.error("增加用户错误", e, this.getClass());
			throw new ServiceException("增加用户错误", e);
		}
	}

	public void updateChannel(ChannelEntity channel) throws ServiceException {
			try {
				channelMapper.update(channel);
			} catch (SQLException e) {
				WqLogger.error("更新用户错误", e, this.getClass());
				throw new ServiceException("更新用户错误", e);
			}
	}

	public ChannelEntity queryChannelById(Integer id) throws ServiceException {

		try {
			return  channelMapper.queryById(id);
		} catch (SQLException e) {
			WqLogger.error("查询用户错误", e, this.getClass());
			throw new ServiceException("查询用户错误", e);
		}
		
	}

	public ResultList<ChannelEntity> queryChannelList(Integer parentId,Pagination page)
			throws ServiceException {
		ResultList<ChannelEntity> resList = new ResultListImpl<ChannelEntity>();
		Map<String , Object> parameters = new HashMap<String,Object>();
		List<ChannelEntity> list = new ArrayList<ChannelEntity>();
		
		try {
				parameters.put("parentId",parentId);
				if(page!=null){
					// 获取总条目数
					Long totalCount = channelMapper.queryCount(parameters);
					page.setTotalCount(totalCount.intValue());
					parameters.put("minnum", page.getStartNo());
					parameters.put("pagesize", page.getPageSize());
				}

				// 获取列表
				list = channelMapper.queryList(parameters);
			
		} catch (SQLException e) {
			WqLogger.error("查询用户列表错误", e, this.getClass());
			throw new ServiceException("查询用户列表错误", e);
		}
		resList.setPage(page);
		resList.setResults(list);
		return resList;
	}

	public List<ChannelTree> queryChannelTree(Integer parentId)
			throws ServiceException {
		Map<String , Object> parameters = new HashMap<String,Object>();

		List<ChannelTree> list = new ArrayList<ChannelTree>();
		
		try {
			// 获取列表
			parameters.put("parentId", parentId);
			list = channelMapper.queryTree(parameters);
			
		} catch (SQLException e) {
			WqLogger.error("查询用户列表错误", e, this.getClass());
			throw new ServiceException("查询用户列表错误", e);
		}

		return list;
		
	}

}

四、Controller

(省略setter,getter)

/**       
 * 类描述: 栏目管理功能控制器  
 * 创建人:周磊  
 * 创建时间:2013-9-12 下午10:17:23      
 * @version v1.0      
 */ 
@Controller
@Scope("prototype")
public class ChannelAction extends BaseAction{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Autowired
	private ChannelService channelService;
	
	private Integer id;
	
	private Integer[] ids;
	
	private Integer parentId;
	
	private ChannelEntity channel ;
	
	private ResultList<ChannelEntity> channelResultList ;
	
	private List<ChannelTree> channelChild;
	
	/**
	 * 标记是否有更改,以确定是否刷新栏目树
	 */
	private Integer refresh;
	
	private ChannelType[] channelTypes;


	public String queryChannelList() {
		
		channelResultList = channelService.queryChannelList(id, null);
		return "channelList";
	}    
	public String queryChannelChildTable() {
		//当前父节点
		channel = channelService.queryChannelById(id);
		//查找孩子节点
		channelResultList = channelService.queryChannelList(id, null);
		for(ChannelEntity ch:channelResultList.getResults()){
			System.out.println(ch.getName());
		}
		return "channelChildTable";
	}    
	
	public String queryChannelChildTree() {
		channelChild = channelService.queryChannelTree(id);
		return "channelChildTree";
	}    
	
	public String toAddChannel() {
		channelTypes = ChannelType.values();

		channel = channelService.queryChannelById(id);
//		parentId = channel.getId();
		return "channelAdd" ;
	}
	
	public String addChannel() {
		channel.setCreateDate(new Date());
		channel.setParentId(id);
		try {
			channelService.insertChannel(channel);
			refresh = 1 ; 
		} catch (ServiceException e) {
			refresh = 0;
			e.printStackTrace();
		}
		return SUCCESS;
	}
	
	public String toUpdateChannel() {
		channelTypes = ChannelType.values();

		channel = channelService.queryChannelById(id);
		return "channelUpdate";
	}
	
	public String updateChannel(){
		try {
			channelService.updateChannel(channel);
			refresh = 1;
		} catch (ServiceException e) {
			refresh = 0;
			e.printStackTrace();
		}
		id=parentId;
		return SUCCESS;
	}
	
	public String deleteChannel() {
		try {
			channelService.deleteChannel(ids);
			id=parentId;
			refresh = 1;
		} catch (ServiceException e) {
			refresh = 0;
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return SUCCESS;
	}
	

struts.xml对channel controller的配置:

<package name="channel" namespace="/channel" extends="authorityPackage,json-default">
		<action name="channel_*" class="org.boston.seuaa.action.ChannelAction" method="{1}">
			<interceptor-ref name="permissionStack" />
			<result name="success" type="redirectAction">channel_queryChannelChildTable.action?id=${id}&refresh=${refresh}</result>
			<result name="input">/pages/index.jsp</result>
			<result name="channelList">/pages/channel/channelList.jsp</result>
			<result name="channelChildTable">/pages/channel/channelChildTable.jsp</result>
			<result name="channelChildTree" type="json">
				 <param name="root">channelChild</param>
			</result>
			<result name="channelAdd">/pages/channel/channelAdd.jsp</result>
			<result name="channelUpdate">/pages/channel/channelUpdate.jsp</result>
			<result name="channelDetail">/pages/channel/channelDetail.jsp</result>
			
		</action>
	</package>


六、开发视图层

实现左边树,右边表格,点击左边树层,在表格中显示该层的子栏目信息。如图:


代码如下:channelList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href=http://www.mamicode.com/"/resources/css/admin/main.css"/>>
加表格视图通过iframe插入到list中:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href=http://www.mamicode.com/"/resources/css/admin/main.css"/>>
七、JS包装效果实现:

(function($){
	$.ajaxCheck = function(data) {
		if(data.result) return true;
		else {
			alert(data.msg);
			return false;
		}
	}
	$.fn.mysorttable = function(opts) {
		var _isSort = false;
		var sortEle = $(this).find("tbody");
		var _that = this;
		var setting = $.extend({
			begin:"beginOrder",
			save:"saveOrder"
		},opts||{});
		sortEle.sortable({
			axis:"y",
			helper:function(e,ele) {
				//原始元素的td对象
				var _original = ele.children();
				var _helper = ele.clone();
				_helper.children().each(function(index){
					$(this).width(_original.eq(index).width());
				});
				_helper.css("background","#aaf");
				return _helper;
			},
			update:function(e,ui) {
				setOrders();
			}
		});
		
		sortEle.sortable("disable");
		
		$("#"+setting.begin).click(beginOrders);
		
		$("#"+setting.save).click(saveOrders);
		
		function beginOrders() {
			if(!_isSort) {
				$(_that).find("thead tr").append("<td>序号</td>");
				setOrders();
				$(_that).find("tfoot tr").append("<td>拖动排序</td>");
				sortEle.sortable("enable");
				_isSort = true;
			} else {
				alert("已经处于排序状态");
			}
		}
		
		function saveOrders() {
			if(_isSort) {
				var idArg = sortEle.sortable("serialize",{key:"ids"});
				$.post("updateSort?"+idArg,function(data){
					if($.ajaxCheck(data)) {
						$(_that).find("tr").each(function(){
							$(this).children().last().remove();
						});
						sortEle.sortable("disable");
						_isSort = false;
					}
				});
			} else {
				alert("还不是排序状态");
			}
		}
		
		function setOrders() {
			$(_that).find("tbody tr").each(function(index){
				if(_isSort) {
					$(this).find("td:last").html((index+1));
				} else
					$(this).append("<td>"+(index+1)+"</td>");
			});
		}
		return sortEle;
	}
	
	//树展现
	$.fn.mytree = function(opts) {
		var setting = $.extend({
			data:{
				simpleData:{
					enable: true,
					idKey: "id",
					pIdKey: "parentId",
					rootPId: 0
				}
			},
			view: {
//				dblClickExpand: false,允许双击展开树
				selectedMulti: false
			},
			async: {
				enable: true,
//				url: opts?(opts.url||"channel_queryChannelList.action"):"channel_queryChannelList.action"
				url:"channel_queryChannelChildTree.action",
				autoParam:["id=parentId"],//用来指定树的传递参数的key的名称
				otherParam: { "ids":"1", "name":"test"}//用来传递其它的参数,ids=1,name=test
				
			},
			mine: {
				listChild:1,
				srcElement:"#cc"
			},
			callback:{
				onAsyncSuccess:function(){
					t.expandAll(true);
				}

			}
		},opts||{});
		
		var _mine = setting.mine;
		var t = $.fn.zTree.init($(this), setting);
		t.getCheckParentNodes = getCheckParentNodes;
		t.getCheckChildNodes = getCheckChildNodes;
		if(_mine.listChild) {
			t.setting.callback.onClick = listChild;
		}
		
		function listChild(event,treeId,treeNode) {
			//alert("treeNode.id="+treeNode.id);
			//单击展开树
			$(_mine.srcElement).attr("src","channel_queryChannelChildTable.action?id="+treeNode.id);
		}
		
		function getCheckParentNodes(treeNode,checked) {
			var ps = new Array();
			var pn;
			while((pn=treeNode.getParentNode())) {
				if(pn.checked==checked) ps.push(pn);
				treeNode = pn;
			}
			return ps;
		}
		//第三个参数存储所有子节点
		function getCheckChildNodes(treeNode,checked,cs) {
			var ccs;
			if((ccs=treeNode.children)) {
				for(var i=0;i<ccs.length;i++) {
					var c = ccs[i];
					if(c.checked==checked) {
						cs.push(c);
					}
					getCheckChildNodes(c,checked,cs);
				}
			}
		}
		return t;
	}
	
	$.fn.myaccordion = function(opts) {
		var settings = $.extend({
			selectedClz:"navSelected",
			titleTagName:"h3"
		},opts||{});
		var titleNode = $(this).find("ul>"+settings.titleTagName);
		var selectedNode = $(this).find("ul."+settings.selectedClz+">"+settings.titleTagName);
		titleNode.css("cursor","pointer");
		titleNode.nextAll().css("display","none");
		selectedNode.nextAll().css("display","block");
		titleNode.click(function(){
			var checked = $(this).parent().hasClass(settings.selectedClz);
			if(checked) {
				$(this).parent().removeClass(settings.selectedClz);
				$(this).nextAll().slideUp();
			} else {
				$(this).parent().addClass(settings.selectedClz);
				$(this).nextAll().slideDown();
			}
		});
	};
	
	$.fn.trColorChange = function(opts) {
		var settings = $.extend({
			overClz:"trMouseover",
			evenClz:"trEvenColor"
		},opts||{});
		$(this).find("tbody tr:even").addClass(settings.evenClz);
		$(this).find("tbody tr").on("mouseenter mouseleave",function(){
			$(this).toggleClass(settings.overClz);
		});
	};
	
	$.fn.confirmOperator = function(opts) {
		var settings = $.extend({
			msg:"该操作不可逆,确定进行该操作吗?",
			eventName:"click"
		},opts||{});
		$(this).on(settings.eventName,function(event){
			if(!confirm(settings.msg)) {
				event.preventDefault();
			}
		});
	}
})(jQuery)

栏目添加视图:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="/base/taglib.jsp"%>
<%@include file="/base/base.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href=http://www.mamicode.com/"/resources/css/admin/main.css"/>>

七、首页栏目展现





【项目总结:波士顿东大校友会】CMS栏目个性化设置