فهرست منبع

用户行为记录优化

huangzhiguo 2 سال پیش
والد
کامیت
43e7556ef1

+ 1 - 1
src/main/java/com/caimei365/tools/listener/IpSaveListener.java

@@ -175,7 +175,7 @@ public class IpSaveListener implements RocketMQListener<String> {
             }
         }
         // 用户行为记录
-        if ("/user/record/StatisticsPc".equals(ipSavePo.getRequestUrl().trim()) || "/user/record/StatisticsApp".equals(ipSavePo.getRequestUrl().trim())) {
+        if ("/user/record/Statistics".equals(ipSavePo.getRequestUrl().trim())) {
             recordService.insertRecord(ipSavePo);
         }
         ipSaveService.save(ipSavePo);

+ 21 - 0
src/main/java/com/caimei365/tools/mapper/CmBehaviorRecordMapper.java

@@ -3,6 +3,8 @@ package com.caimei365.tools.mapper;
 import com.caimei365.tools.model.po.CmBehaviorRecordPo;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * Description
  *
@@ -18,4 +20,23 @@ public interface CmBehaviorRecordMapper {
      * @return
      */
     void insertRecord(CmBehaviorRecordPo cmBehaviorRecordPo);
+
+    /**
+     * 当天访问网站IP、userId
+     * @param cmBehaviorRecordPo
+     */
+    List<CmBehaviorRecordPo> toDateRecode(CmBehaviorRecordPo cmBehaviorRecordPo);
+
+    /**
+     * 当天访问网站IP、userId的详细数据
+     * @param cmBehaviorRecordPo
+     */
+    List<CmBehaviorRecordPo> toDateIPTimeRecode(CmBehaviorRecordPo cmBehaviorRecordPo);
+
+    /**
+     * 计算真是访问时长
+     * @param cmBehaviorRecordPo
+     */
+    void updateDuration(CmBehaviorRecordPo cmBehaviorRecordPo);
 }
+

+ 29 - 1
src/main/java/com/caimei365/tools/model/po/CmBehaviorRecordPo.java

@@ -17,7 +17,7 @@ public class CmBehaviorRecordPo {
     /**
      * 访问人IP地址
      */
-    private String ip;
+    private String IP;
     /**
      * 用户id、0为游客
      */
@@ -62,4 +62,32 @@ public class CmBehaviorRecordPo {
      * 访问日期
      */
     private String accessDate;
+    /**
+     * 开始时间
+     */
+    private String startTime;
+    /**
+     * 结束时间
+     */
+    private String endTime;
+    /**
+     * 浏览器链接
+     */
+    private String referer;
+    /**
+     * 访问来源
+     */
+    private String accessSource;
+    /**
+     * 访问客户端  0:网站 1:小程序
+     */
+    private String accessClient;
+    /**
+     * 是否计算访问时长 0未计算 1已计算
+     */
+    private String isReckon;
+    /**
+     * ip所属地
+     */
+    private String region;
 }

+ 2 - 0
src/main/java/com/caimei365/tools/service/CmBehaviorRecordService.java

@@ -11,4 +11,6 @@ import com.caimei365.tools.model.po.IpSavePo;
  */
 public interface CmBehaviorRecordService {
     void insertRecord(IpSavePo ipSavePo);
+
+    void updateBehaviorTime();
 }

+ 159 - 7
src/main/java/com/caimei365/tools/service/impl/CmBehaviorRecordServiceImpl.java

@@ -1,5 +1,6 @@
 package com.caimei365.tools.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.caimei365.tools.mapper.CmBehaviorRecordMapper;
 import com.caimei365.tools.model.po.CmBehaviorRecordPo;
 import com.caimei365.tools.model.po.IpSavePo;
@@ -9,10 +10,17 @@ import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 import java.util.TimeZone;
 
 /**
@@ -29,10 +37,10 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
 
     @Override
     public void insertRecord(IpSavePo ipSavePo) {
-        if ("/user/record/StatisticsPc".equals(ipSavePo.getRequestUrl().trim()) || "/user/record/StatisticsApp".equals(ipSavePo.getRequestUrl().trim())) {
+        if ("/user/record/Statistics".equals(ipSavePo.getRequestUrl().trim())) {
             log.info("用户行为记录=================》" + ipSavePo.getIp());
             CmBehaviorRecordPo cmBehaviorRecordPo = new CmBehaviorRecordPo();
-            cmBehaviorRecordPo.setIp(ipSavePo.getIp());
+            cmBehaviorRecordPo.setIP(ipSavePo.getIp());
             if (StringUtils.isNotBlank(ipSavePo.getUserId())) {
                 cmBehaviorRecordPo.setUserId(ipSavePo.getUserId());
             } else {
@@ -132,14 +140,31 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
                             }
                         }
                     }
-                    // 访问时长
-                    if (str.startsWith("accessDuration") && str.contains("=")) {
+                    // 访问客户端 0:网站 1:小程序
+                    if (str.startsWith("accessClient") && str.contains("=")) {
                         String[] split1 = str.split("=");
+                        cmBehaviorRecordPo.setAccessClient("0");
                         if (split1.length > 1) {
                             String value = split1[1];
                             String trim = value.trim();
                             if (StringUtils.isNotBlank(trim)) {
-                                cmBehaviorRecordPo.setAccessDuration(trim);
+                                cmBehaviorRecordPo.setAccessClient(trim);
+                            }
+                        }
+                    }
+                    // 浏览器链接
+                    if (str.startsWith("referer") && str.contains("=")) {
+                        String[] split1 = str.split("=");
+                        if (split1.length > 1) {
+                            String value = split1[1];
+                            String trim = value.trim();
+                            if (StringUtils.isNotBlank(trim)) {
+                                log.info("referer============》"+trim);
+                                // 浏览器链接
+                                cmBehaviorRecordPo.setReferer(trim);
+                                // 访问来源
+                                String source = source(trim);
+                                cmBehaviorRecordPo.setAccessSource(source);
                             }
                         }
                     }
@@ -148,11 +173,138 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
 
             Date date = new Date();
             cmBehaviorRecordPo.setAccessTime(date);
-
+            cmBehaviorRecordPo.setAccessDuration("5000");
             SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
             String format = simpleDateFormat.format(date);
             cmBehaviorRecordPo.setAccessDate(format);
+            cmBehaviorRecordPo.setIsReckon("0");
             recordMapper.insertRecord(cmBehaviorRecordPo);
         }
     }
+
+    @Override
+    public void updateBehaviorTime() {
+        log.info("计算实际访问时长==================》");
+        long t1 = 0;
+        long t2 = 0;
+        Long duration = 0L;
+        String region = "";
+        CmBehaviorRecordPo cmBehaviorRecordPo = new CmBehaviorRecordPo();
+        CmBehaviorRecordPo cmBehaviorRecord = new CmBehaviorRecordPo();
+        Date date = new Date();
+        // 获取当前时间日期
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        String format = simpleDateFormat.format(new Date(date.getTime() - 600000));
+        cmBehaviorRecordPo.setAccessDate(format);
+        // 当天访问系统ip和userID
+        List<CmBehaviorRecordPo> recordPos = recordMapper.toDateRecode(cmBehaviorRecordPo);
+        for (CmBehaviorRecordPo behaviorRecordPo: recordPos) {
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            // 当前时间
+            String timeEnd = dateFormat.format(date);
+            //  一小时前时间
+            Calendar c = Calendar.getInstance();
+            c.set(Calendar.HOUR_OF_DAY,(c.get(Calendar.HOUR_OF_DAY) - 1));
+            String timeStart = dateFormat.format(c.getTime());
+
+            behaviorRecordPo.setStartTime(timeStart);
+            behaviorRecordPo.setEndTime(timeEnd);
+            // 获取一个小时之内的数据
+            List<CmBehaviorRecordPo> recordPoList = recordMapper.toDateIPTimeRecode(behaviorRecordPo);
+            if (recordPoList.size() <= 0) {
+                continue;
+            }
+            for (int i = 0; i < recordPoList.size() ; i++) {
+                if (i != recordPoList.size() - 1) {
+                    t1 = recordPoList.get(i).getAccessTime().getTime();
+                    t2 = recordPoList.get(i+1).getAccessTime().getTime();
+                    duration = t2 - t1;
+                    // 修改实际访问时长
+                    cmBehaviorRecord.setRecordID(recordPoList.get(i).getRecordID());
+                    cmBehaviorRecord.setAccessDuration(duration.toString());
+                    cmBehaviorRecord.setIsReckon("1");
+                    // 确定ip所属地
+
+                    try {
+                        region = recordIp(recordPoList.get(i).getIP());
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    cmBehaviorRecord.setRegion(region);
+                    recordMapper.updateDuration(cmBehaviorRecord);
+                }
+            }
+        }
+    }
+
+
+    // 获取IP对应地址 ---- 太平洋
+    public static String recordIp(String ip) throws IOException {
+        URL url = null;
+        HttpURLConnection connection = null;
+        String encoding = "gbk";
+        String text = "";
+        String line = "";
+        String region = "";
+        String urlStr = "http://whois.pconline.com.cn/ipJson.jsp?ip="+ip+"&json=true";
+        try {
+            url = new URL(urlStr);
+            connection = (HttpURLConnection) url.openConnection();	//新建链接实例
+            connection.setConnectTimeout(20000);	//设置链接超时时间,单位毫秒
+            connection.setReadTimeout(20000);		//设置读取数据超时时间,单位毫秒
+            connection.setDoOutput(true);		//是否打开输出流true|false
+            connection.setDoInput(true);		//是否打开输入流true|false
+            connection.setRequestMethod("GET");		// 提交方式get|post
+            connection.setUseCaches(false);		// 是否加入缓存true|false
+            connection.connect();	//打开链接端口
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding));	// 往对端写完数据对端服务器返回数据。以BufferedReader流来读取
+
+            while ((line = reader.readLine()) != null) {
+                text += line+"\n";
+            }
+            reader.close();
+
+            JSONObject jsonObject = JSONObject.parseObject(text);
+            region = jsonObject.get("addr").toString();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } finally {
+            if (connection != null) {
+                connection.disconnect();	//关闭谅解
+            }
+        }
+        return region;
+    }
+
+    private String source(String link) {
+        if (link.contains("www.baidu.com")) {
+            return "1";
+        }
+        if (link.contains("www.so.com")) {
+            return "2";
+        }
+        if (link.contains("www.google.cn")) {
+            return "3";
+        }
+        if (link.contains("m.sm.cn")) {
+            return "4";
+        }
+        if (link.contains("toutiao.com")) {
+            return "5";
+        }
+        if (link.contains("www.sogou.com")) {
+            return "6";
+        }
+        if (link.contains("servicewechat.com")) {
+            return "7";
+        }
+        if (link.contains("www.caimei365.com")) {
+            return "0";
+        }
+        if (link.contains("zzjtest.gz.aeert.com")) {
+            return "0";
+        }
+        return null;
+    }
 }

+ 11 - 0
src/main/java/com/caimei365/tools/task/CmOrganValueSystemTask.java

@@ -1,5 +1,6 @@
 package com.caimei365.tools.task;
 
+import com.caimei365.tools.service.CmBehaviorRecordService;
 import com.caimei365.tools.service.CmOrganValueSystemService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -23,6 +24,8 @@ public class CmOrganValueSystemTask {
 
     @Resource private CmOrganValueSystemService cmOrganValueSystemService;
 
+    @Resource private CmBehaviorRecordService cmBehaviorRecordService;
+
     /**
      * 每月一号更新用户活跃状态、用户价值
      */
@@ -30,4 +33,12 @@ public class CmOrganValueSystemTask {
     public void organData(){
         cmOrganValueSystemService.insertOrgan();
     }
+
+    /**
+     * 每小时统计计算真实访问时长
+     */
+    @Scheduled(cron = "0 0/10 * * * ?")
+    public void behaviorAccessDuration() {
+        cmBehaviorRecordService.updateBehaviorTime();
+    }
 }

+ 22 - 2
src/main/resources/mapper/CmBehaviorRecordMapper.xml

@@ -2,7 +2,27 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.caimei365.tools.mapper.CmBehaviorRecordMapper">
     <insert id="insertRecord">
-        INSERT INTO cm_behavior_record (IP, userID, pagePath, pageType, pageLabel, behaviorType, productID, accessTime, accessDuration, accessDate)
-        VALUES(#{ip},#{userId},#{pagePath},#{pageType},#{pageLabel},#{behaviorType},#{productId},#{accessTime},#{accessDuration},#{accessDate})
+        INSERT INTO cm_behavior_record (IP, userID, pagePath, pageType, pageLabel, behaviorType, productID, accessTime, accessDuration, accessDate,referer,accessSource,accessClient,isReckon)
+        VALUES(#{IP},#{userId},#{pagePath},#{pageType},#{pageLabel},#{behaviorType},#{productId},#{accessTime},#{accessDuration},#{accessDate},#{referer},#{accessSource},#{accessClient},#{isReckon})
     </insert>
+
+    <select id="toDateRecode" resultType="com.caimei365.tools.model.po.CmBehaviorRecordPo">
+        SELECT IP, userID FROM cm_behavior_record WHERE accessDate = #{accessDate} GROUP BY IP, userID
+    </select>
+
+    <select id="toDateIPTimeRecode" resultType="com.caimei365.tools.model.po.CmBehaviorRecordPo">
+        SELECT recordID, IP, userID, accessTime FROM cm_behavior_record WHERE IP = #{IP} AND userID = #{userId} AND isReckon = 0
+                                                                          AND accessTime BETWEEN #{startTime} and #{endTime}
+        union
+        SELECT recordID, IP, userID, accessTime FROM cm_behavior_record WHERE IP = #{IP} AND isReckon = 0 AND accessDate = #{accessDate} AND userID = #{userId}
+        ORDER BY accessTime ASC
+    </select>
+    <update id="updateDuration">
+        UPDATE cm_behavior_record
+        SET accessDuration = #{accessDuration},
+            isReckon = #{isReckon},
+            region = #{region}
+        WHERE recordID = #{recordID}
+    </update>
 </mapper>
+