文章引子
在我們日常網站開發中,涉及到頁面統計功能,通常我們會採用百度統計、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等,感興趣的朋友可以繼續研究,如本案例能幫助到小夥伴們,不勝榮幸。