文章引子
在我们日常网站开发中,涉及到页面统计功能,通常我们会采用百度统计、CNZZ 等类似这样专业第三方统计平台,只需在页面插入一句简单的JS脚本即可实现复杂的页面统计功能,本次案例我们是局域网网站开发,类似政府部门、事业单位等这样的内网环境下的页面统计就不能用这些三方了,笔者刚开始想着很简单的一个功能,百度一下应该很多吧,但是很失望,没有一个像样的轮子,只能左思右想如何实现了,在一番思考之下,笔者基本实现了如下功能:【今日访问量:74 总访问量:179】,为避免重复造轮子,笔者做了如下总结:
需求描述:
统计网站(局域网)今日用户访问量,统计网站全部访问量。
实现思路:
前端:采用AJAX 调用接口,返回今日和总访问量,然后渲染到页面;
后台:基于SSM的框架搭建,一旦用户调用接口,即可更新数据库,然后返回最新统计;
遇到问题:
总访问量很好统计,只要调用了统计接口,数据库+1就行;
今日访问量却如何统计?笔者思考后做了如下的操作,简单说就是先获取数据库的时间,与当前时间做对比,如果一致说明是今天的统计数据,正常+1,如果不一致,说明今天这是第一次用户访问,那么就需要更新记录时间,同事设置今日为1,总访问量依旧+1,写到这里,不知道读者有没有迷糊,笔者也是思考良久,在众多方案中选了一个比较规矩简单实用的,话不多说,上代码;
核心代码如下(注:可能部分涉及相关的代码,如配置等没有放出来,如大家有疑问可留言,笔者酌情答复):
1、后台代码
数据库
CREATE TABLE `IM_PAGE_VIEW` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`currdate` date DEFAULT NULL,
`today` int(20) DEFAULT '0',
`history` int(50) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
模型数据
public class PageView {
private int id;
private int today;
private int history;
private Date currdate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getToday() {
return today;
}
public void setToday(int today) {
this.today = today;
}
public int getHistory() {
return history;
}
public void setHistory(int history) {
this.history = history;
}
public Date getCurrdate() {
return currdate;
}
public void setCurrdate(Date currdate) {
this.currdate = currdate;
}
}
数据层
/** 页面统计*/
PageView getPageViewById(@Param("id") Integer id);
int updatePageView(@Param("id") Integer id, @Param("pageView") PageView pageView);
<!-- 页面统计 -->
<resultMap id="withPageViewResultMap" type="PageView">
<id column="id" property="id"></id>
<result column="today" property="today"></result>
<result column="history" property="history"></result>
<result column="currdate" property="currdate"></result>
</resultMap>
<select id="getPageViewById" parameterType="Integer" resultMap="withPageViewResultMap">
SELECT * FROM IM_PAGE_VIEW WHERE id = #{id}
</select>
<update id="updatePageView" parameterType="PageView">
UPDATE IM_PAGE_VIEW SET currdate = #{pageView.currdate},today = #{pageView.today},history = #{pageView.history} WHERE id = #{id}
</update>
业务层
@Override
public PageView getPageViewById(Integer id) {
// TODO Auto-generated method stub
return userMapper.getPageViewById(id);
}
@Override
public int updatePageView(Integer id, PageView pageView) {
// TODO Auto-generated method stub
return userMapper.updatePageView(id, pageView);
}
控制层
/**
* 页面统计
* @return
*/
@CrossOrigin
@RequestMapping(value = "/userPageViewApi", method = RequestMethod.GET)
@ResponseBody
public ResultData userPageViewApi() {
PageView pageView = userService.getPageViewById(1);
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd");
//系统时间
String systemDate = dateFormat.format(new Date());
//记录时间
String pageViewDate = dateFormat.format(pageView.getCurrdate());
if (systemDate.equals(pageViewDate)) { //今天
pageView.setToday(pageView.getToday()+1);
pageView.setHistory(pageView.getHistory()+1);
}else { //不是今天了
pageView.setToday(1);
pageView.setCurrdate(new Date());
pageView.setHistory(pageView.getHistory()+1);
}
int res = userService.updatePageView(1, pageView);
if (res != 1) {
return new ResultData(201, "统计失败");
}
return new ResultData(200, "统计成功",pageView);
}
2、前端代码
<!-- 引入外部JS -->
<script src="../js/jquery-3.1.1.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/jquery.cookie.js"></script>
<!-- 业务处理 -->
<script type="text/javascript">
// 头部文件和尾部文件
$(function () {
pageViewStatistics();
})
//页面访问量统计
function pageViewStatistics(){
$.ajax({
type: "GET",
url: "http://localhost:8080/ImageManagement/user/userPageViewApi",
dataType: 'json',
success: function (result) {
if (result.code == 200) {
console.log(result.toString());
$.cookie('user_pv_today', result.data.today);
$.cookie('user_pv_history', result.data.history);
$(".pv").html("今日访问量:<span class='text-success'>"+ $.cookie('user_pv_today') +"</span> 总访问量:<span class='text-success'>"+ $.cookie('user_pv_history')+"</span>");
}else {
$(".pageview").html("");
}
}
});
}
</script>
最新页面效果
至此,笔者基本实现了最初的页面统计需求,其实还有很多实现方案,比如接口监听、AOP等,感兴趣的朋友可以继续研究,如本案例能帮助到小伙伴们,不胜荣幸。