自己动手编写JEECMS自定义栏目统计标签

今天想在给Java客二级版面加入栏目文章统计效果,如下图,

查看JEECMS的源代码发现开发者版本还没有类似现成的统计标签,一种解决的办法是使用现有的JEECMS标签,像这样Struts( [@cms_content_list channel=id]${tag_list?size}[/@cms_content_list]) ,但是这样的做法非常地低效,原因是[@cms_content_list]标签会把所有当前栏目的文章内容对象查询出来,做全表查询!

没办法啊!!!为了网站访问效率,只好自己写一个统计标签吧。那下面就以[@cms_channel_statistic]为例说下如何在JEECMS加入自定义标签。

 

第一步:编写装载统计信息的Entity

/**
 * 频道统计实体类
 * @author www.javake.net
 */
public class ChannelStatistics {
	/**
	 * 文章总数
	 */
	private long contentAllCount;
	/**
	 * 待审核文章总数
	 */
	private long contentCheckingCount;
	/**
	 * 评论总数
	 */
	private long commentCount;
	/**
	 * 阅读总数
	 */
	private long viewCount;
	public long getContentAllCount() {
		return contentAllCount;
	}
	public void setContentAllCount(long contentAllCount) {
		this.contentAllCount = contentAllCount;
	}
	public long getContentCheckingCount() {
		return contentCheckingCount;
	}
	public void setContentCheckingCount(long contentCheckingCount) {
		this.contentCheckingCount = contentCheckingCount;
	}
	public long getCommentCount() {
		return commentCount;
	}
	public void setCommentCount(long commentCount) {
		this.commentCount = commentCount;
	}
	public long getViewCount() {
		return viewCount;
	}
	public void setViewCount(long viewCount) {
		this.viewCount = viewCount;
	}
}


第二步:编写栏目信息统计的Dao接口。暂时只实现文章总数统计,待审核文章统计,评论总数。

/**
 * 栏目信息统计Dao接口
 * @author www.javake.net
 */
public interface CmsChannelStatisticDao {
	/**
	 * 当前栏目文章统计
	 * @param restrictions
	 * @return
	 */
	public long contentStatistic(Map<String, Object> restrictions);
	/**
	 * 当前栏目待审核文章统计
	 * @param restrictions
	 * @return
	 */
	public long contentCheckingStatistic(Map<String, Object> restrictions);
	/**
	 * 当前栏目评论统计
	 * @param restrictions
	 * @return
	 */
	public long commentStatistic(Map<String, Object> restrictions);
}


 

第三步:编写Dao接口的实现。

/**
 * 栏目信息统计Dao实现类
 * @author www.javake.net
 */
import static com.jeecms.cms.entity.main.Content.ContentStatus.passed;
import static com.jeecms.cms.entity.main.Content.ContentStatus.prepared;
import static com.jeecms.cms.entity.main.Content.ContentStatus.rejected;
import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;
import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;
import static com.jeecms.cms.statistic.CmsStatistic.SITEID;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.jeecms.cms.entity.main.Content.ContentStatus;
import com.jeecms.common.hibernate3.Finder;
import com.jeecms.common.hibernate3.HibernateSimpleDao;
@Repository
public class CmsChannelStatisticDaoImpl extends HibernateSimpleDao
			implements CmsChannelStatisticDao{
	/**
	 * 获取文章总数
	 */
	public long contentStatistic(Map<String, Object> restrictions) {
		Finder f = createCacheableFinder("select count(*) from Content bean");
		Integer channelId = (Integer) restrictions.get(CHANNELID);
		if (channelId != null) {
			f.append(" join bean.channel channel,Channel parent");
			f.append(" where channel.lft between parent.lft and parent.rgt");
			f.append(" and channel.site.id=parent.site.id");
			f.append(" and parent.id=:parentId");
			f.setParam("parentId", channelId);
		} else {
			f.append(" where bean.site.id=:siteId").setParam("siteId",
					restrictions.get(SITEID));
		}
		return (Long) find(f).iterator().next();
	}
	
	private long contentStatistic(Map<String, Object> restrictions,ContentStatus status) {
		Finder f = createCacheableFinder("select count(*) from Content bean");
		if (prepared == status || passed == status || rejected == status) {
			f.append(" join bean.contentCheckSet check");
		}
		Integer channelId = (Integer) restrictions.get(CHANNELID);
		if (channelId != null) {
			f.append(" join bean.channel channel,Channel parent");
			f.append(" where channel.lft between parent.lft and parent.rgt");
			f.append(" and channel.site.id=parent.site.id");
			f.append(" and parent.id=:parentId");
			f.setParam("parentId", channelId);	
		} else {
			f.append(" where bean.site.id=:siteId").setParam("siteId",
					restrictions.get(SITEID));
		}
		if (prepared == status || passed == status) {
			f.append(" and check.rejected=false");
		} else if (rejected == status) {
			f.append(" and check.rejected=true");
		}
		return (Long) find(f).iterator().next();
	}
	
	/**
	 * 待审核文章总数
	 * @param restrictions
	 * @param status
	 * @return
	 */
	public long contentCheckingStatistic(Map<String, Object> restrictions) {
		return contentStatistic(restrictions,ContentStatus.prepared);
	}
	public long commentStatistic(Map<String, Object> restrictions) {
		Finder f = createCacheableFinder("select count(*) from CmsComment bean ");
		Integer channelId = (Integer) restrictions.get(CHANNELID);
		if (channelId != null) {
			f.append(" join bean.channel channel,Channel parent");
			f.append(" where channel.lft between parent.lft and parent.rgt");
			f.append(" and channel.site.id=parent.site.id");
			f.append(" and parent.id=:parentId");
			f.setParam("parentId", channelId);	
		} else {
			f.append(" where bean.site.id=:siteId").setParam("siteId",
					restrictions.get(SITEID));
		}
		Boolean isReplyed = (Boolean) restrictions.get(ISREPLYED);
		if (isReplyed != null) {
			if (isReplyed) {
				f.append(" and bean.replayTime is not null");
			} else {
				f.append(" and bean.replayTime is null");
			}
		}
		return (Long) find(f).iterator().next();
	}
	
	private Finder createCacheableFinder(String hql) {
		Finder finder = Finder.create(hql);
		finder.setCacheable(true);
		return finder;
	}
}


 

第四步:编写栏目统计的FreeMarker标签类。这里可以输入两个参数,一个是id(栏目id),一个是siteId(站点id)。这两个参数可在使用标签的时候输入。

/**
 * 栏目统计
 * @author www.javake.net
 */
import static com.jeecms.common.web.freemarker.DirectiveUtils.OUT_BEAN;
import static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;
import static com.jeecms.cms.statistic.CmsStatistic.SITEID;
import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;
import static com.jeecms.cms.statistic.CmsStatistic.USERID;
import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.jeecms.cms.entity.main.ChannelStatistics;
import com.jeecms.cms.entity.main.CmsSite;
import com.jeecms.cms.statistic.CmsChannelStatisticDao;
import com.jeecms.cms.web.FrontUtils;
import com.jeecms.common.web.freemarker.DirectiveUtils;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
public class CmsChannelStatisticsDirective implements TemplateDirectiveModel{
	/**
	 * 输入参数,站点ID。存在时,获取该站点栏目,不存在时获取当前站点栏目。
	 */
	public static final String PARAM_SITE_ID = "siteId";
	/**
	 * 输入参数,栏目ID。
	 */
	public static final String PARAM_ID = "id";
	@SuppressWarnings("unchecked")
	public void execute(Environment env, Map params, TemplateModel[] loopVars,
			TemplateDirectiveBody body) throws TemplateException, IOException {
		CmsSite site = FrontUtils.getSite(env);
		Integer id = DirectiveUtils.getInt(PARAM_ID, params);
		ChannelStatistics statistics = null;
		Map<String,Object> restrictions = new HashMap<String,Object>();
		Integer siteId = DirectiveUtils.getInt(PARAM_SITE_ID, params);
		if (siteId == null) {
			siteId = site.getId();
		}
		if (id != null ) {
			restrictions.put(CHANNELID, id);		
		} else {
			restrictions.put(SITEID, siteId);
		}
		long contentCount = channelSatistic.contentStatistic(restrictions);
		long contentCheckingCount = channelSatistic.contentCheckingStatistic(restrictions);
		long commentCount = channelSatistic.commentStatistic(restrictions);
		
		statistics = new ChannelStatistics();
		statistics.setCommentCount(commentCount);
		statistics.setContentAllCount(contentCount);
		statistics.setContentCheckingCount(contentCheckingCount);
		
		Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(
				params);
		paramWrap.put(OUT_BEAN, DEFAULT_WRAPPER.wrap(statistics));
		Map<String, TemplateModel> origMap = DirectiveUtils
				.addParamsToVariable(env, paramWrap);
		body.render(env.getOut());
		DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);
	}
	
	@Autowired
	private CmsChannelStatisticDao channelSatistic;

	public void setChannelSatistic(CmsChannelStatisticDao channelSatistic) {
		this.channelSatistic = channelSatistic;
	}
}


 

第五步:在jeecms-context.xml文件中加入CmsChannelStatisticsDirective标签类的bean注入代码。

<!— Author:www.javake.net -->

<bean id="cms_lucene_page"class="com.jeecms.cms.lucene.LuceneDirectivePage"/>

<bean id="cms_advertising"class="com.jeecms.cms.action.directive.CmsAdvertisingDirective"/>

<bean id="cms_channel_statistic" class="com.jeecms.cms.action.directive.CmsChannelStatisticsDirective"/>

 

<!— Author:www.javake.net -->

<property name="freemarkerVariables">

        <map>

            <entry key="uuid"value-ref="uuid"/>

            <entry key="process_time"value-ref="process_time"/>

            <entry key="text_cut"value-ref="text_cut"/>

            <entry key="html_cut"value-ref="html_cut"/>

            <entry key="cms_pagination"value-ref="cms_pagination"/>

            <entry key="cms_channel_list"value-ref="cms_channel_list"/>

            <entry key="cms_channel_page"value-ref="cms_channel_page"/>

            <entry key="cms_channel"value-ref="cms_channel"/>

            <entry key="cms_content"value-ref="cms_content"/>

            <entry key="cms_content_list"value-ref="cms_content_list"/>

            <entry key="cms_content_page"value-ref="cms_content_page"/>

            <entry key="cms_tag_list"value-ref="cms_tag_list"/>

            <entry key="cms_tag_page"value-ref="cms_tag_page"/>

            <entry key="cms_topic_list"value-ref="cms_topic_list"/>

            <entry key="cms_topic_page"value-ref="cms_topic_page"/>

            <entry key="cms_comment_list"value-ref="cms_comment_list"/>

            <entry key="cms_comment_page"value-ref="cms_comment_page"/>

            <entry key="cms_guestbook_ctg_list"value-ref="cms_guestbook_ctg_list"/>

            <entry key="cms_guestbook_list"value-ref="cms_guestbook_list"/>

            <entry key="cms_guestbook_page"value-ref="cms_guestbook_page"/>

            <entry key="cms_vote"value-ref="cms_vote"/>

            <entry key="cms_friendlink_ctg_list"value-ref="cms_friendlink_ctg_list"/>

            <entry key="cms_friendlink_list"value-ref="cms_friendlink_list"/>

            <entry key="cms_lucene_list"value-ref="cms_lucene_list"/>

            <entry key="cms_lucene_page"value-ref="cms_lucene_page"/>

            <entry key="cms_advertising"value-ref="cms_advertising"/>

            <entry key="cms_channel_statistic" value-ref="cms_channel_statistic"/>

            </map>

        </property>

 

第六步:在jeecms-servlet-front.xml文件中配置

<!— Author:www.javake.net -->

<bean id="freemarkerConfig"class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">

        <property name="freemarkerVariables">

            <map>

            <entry key="uuid"value-ref="uuid"/>

            <entry key="process_time"value-ref="process_time"/>

            <entry key="text_cut"value-ref="text_cut"/>

            <entry key="html_cut"value-ref="html_cut"/>

            <entry key="cms_pagination"value-ref="cms_pagination"/>

            <entry key="cms_channel_list"value-ref="cms_channel_list"/>

            <entry key="cms_channel_page"value-ref="cms_channel_page"/>

            <entry key="cms_channel"value-ref="cms_channel"/>

            <entry key="cms_content"value-ref="cms_content"/>

            <entry key="cms_content_list"value-ref="cms_content_list"/>

            <entry key="cms_content_page"value-ref="cms_content_page"/>

            <entry key="cms_tag_list"value-ref="cms_tag_list"/>

            <entry key="cms_tag_page"value-ref="cms_tag_page"/>

            <entry key="cms_topic_list"value-ref="cms_topic_list"/>

            <entry key="cms_topic_page"value-ref="cms_topic_page"/>

            <entry key="cms_comment_list"value-ref="cms_comment_list"/>

            <entry key="cms_comment_page"value-ref="cms_comment_page"/>

            <entry key="cms_guestbook_ctg_list"value-ref="cms_guestbook_ctg_list"/>

            <entry key="cms_guestbook_list"value-ref="cms_guestbook_list"/>

            <entry key="cms_guestbook_page"value-ref="cms_guestbook_page"/>

            <entry key="cms_vote"value-ref="cms_vote"/>

            <entry key="cms_lucene_list"value-ref="cms_lucene_list"/>

            <entry key="cms_lucene_page"value-ref="cms_lucene_page"/>

            <entry key="cms_friendlink_ctg_list"value-ref="cms_friendlink_ctg_list"/>

            <entry key="cms_friendlink_list"value-ref="cms_friendlink_list"/>

            <entry key="cms_advertising"value-ref="cms_advertising"/>

            <entry key="cms_channel_statistic" value-ref="cms_channel_statistic"/>

            </map>

        </property>

 

第七步:到目前为止,核心代码和配置编写完毕啦!!!可以在栏目模板中使用标签了!

<!—Author:www.javake.net-->

( [@cms_channel_statisticid=a.id]${tag_bean.contentAllCount}[/@cms_channel_statistic] )

 

jeecms v9.3 正式版 安装包 更新日志 1、栏目添加选择模型模板只选择一个报错 2、内容复用待审核查询报错(开源版) 3、根栏目添加内容报错 4、后台页面样式调整 5、后台编辑器分页问题 7、数据统计今日数据没有问题 8、公众号推送菜单和群发微信菜单获取微信端消息返回处理 9、OSS管理添加appkey_secretId后台未解密导致数据存储错误 10、会员中心留言列表报错 11、工作流节点空值处理 12、手机模板在静态页生成的情况下url错误处理 13、新增百度主动推送 14、内容删除同时删除静态页(含FTP) 15、栏目内容静态化调整成只生成前10页 16、activation jcaptcha freemarker JAR部分用户反映下载不了,调整pom采用本地jar 17、栏目没有选择模型模板的情况下,发布内容选择不到模型问题处理 JEECMS简介 JEECMS是一款支持栏目模型、内容模型交叉自定义、以及具备支付和财务结算的内容电商为一体内容管理系统:  对于不懂技术的用户来说,只要通过后台的简单设置即可自定义出集新闻管理、图库管理、视频管理、下载系统、文库管理、政务公开、作品管理、产品发布、供求信息、房屋租售、招聘信息、网络问卷调查及留言板于一体的综合性且不失个性化门户网站。  对于技术达人来说,jeecms不仅提供全部源码,而且在研发之初即全面的考虑了二次开发的高效性和代码的高移植性,是一款非常容易上手和二次开发的产品。  JEECMSv8版本是一款集PC互联网、移动互联网和微信网站于一体的网站群管理系统jeecmsV7不仅可以通过H5自适应的方式实现手机网页模板,还可以采用v7专享的移动端模板,实现了同一个网站PC端和移动端所展现的风格或者内容一致或完全不一样的效果,让网站更适应用户的浏览体验。  JEECMSv8版本新增作者投稿、投稿管理、投稿佣金收益管理和内容赞赏功能,集成了支付宝和微信多种场景多终端的支付方案,为下一波内容电商从业人员提供技术动力。 JEECMSv8支持PC网站、手机网站、微信网站、手机APP和可移动触摸大屏,一套系统即可完成五端一体化管理的网站建设 JEECMS页面展示:     相关阅读 同类推荐:CMS系统
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值