From c40f30d375d4108c8514eed49b372cbb7d80bb57 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期三, 15 十月 2025 16:15:01 +0800
Subject: [PATCH] 用户行为分析

---
 framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java          |    5 
 framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java        |   46 +++++++
 framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java            |    8 +
 manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java   |   11 +
 framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java         |   74 ++++++++++++
 framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml                        |  154 +++++++++++++++++++++++++
 framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java   |   41 ++++++
 framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java |   19 +++
 8 files changed, 358 insertions(+), 0 deletions(-)

diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java b/framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java
new file mode 100644
index 0000000..95a9d4a
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java
@@ -0,0 +1,41 @@
+package cn.lili.modules.lmk.domain.query;
+
+import cn.lili.base.AbsQuery;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛琛屼负璁板綍鏌ヨ
+ *
+ * @author peng
+ * @since 2025-09-08
+ */
+@Data
+@ApiModel(value = "ActionRecord鏌ヨ鍙傛暟", description = "鐢ㄦ埛琛屼负璁板綍鏌ヨ鍙傛暟")
+public class StayActionRecordQuery extends AbsQuery {
+    /**
+     * 鐢ㄦ埛id
+     */
+    private String userName;
+    /**
+     * 椤甸潰绫诲瀷
+     */
+    private String pageCode;
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date beginDate;
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endDate;
+}
+
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java
new file mode 100644
index 0000000..37a56cf
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java
@@ -0,0 +1,46 @@
+package cn.lili.modules.lmk.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 鍒嗕韩琛屼负璁板綍瀹炰綋绫�
+ * 瀵瑰簲SQL鏌ヨ缁撴灉鐨勫疄浣撴槧灏�
+ */
+@Data
+public class ShareActionRecordVO {
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    private String nickName;
+    
+    /**
+     * 椤甸潰缂栫爜
+     */
+    private String pageCode;
+    
+    /**
+     * 鍒嗕韩閫夐」锛堝叿浣撳�兼牴鎹笟鍔″畾涔夛級
+     */
+    private String shareOption;
+    
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+    
+    /**
+     * 鍒涘缓鏃堕棿锛堝垎浜涓哄彂鐢熸椂闂达級
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+    
+    /**
+     * 涓枃椤甸潰鍚嶇О
+     */
+    private String pageNameCn;
+}
\ No newline at end of file
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java
new file mode 100644
index 0000000..d310e4c
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java
@@ -0,0 +1,74 @@
+package cn.lili.modules.lmk.domain.vo;
+
+import cn.lili.base.AbsVo;
+import cn.lili.modules.lmk.domain.entity.ActionRecord;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.lang.NonNull;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛琛屼负璁板綍灞曠ず
+ *
+ * @author peng
+ * @since 2025-09-08
+ */
+@Data
+@ApiModel(value = "鐢ㄦ埛琛屼负璁板綍鍝嶅簲鏁版嵁", description = "鐢ㄦ埛琛屼负璁板綍鍝嶅簲鏁版嵁")
+public class StayActionRecordVO  {
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private String userId;
+
+    /**
+     * 鐢ㄦ埛鏄电О
+     */
+    private String nickName;
+
+    /**
+     * 浼氳瘽ID
+     */
+    private String sessionId;
+
+    /**
+     * 椤甸潰缂栫爜
+     */
+    private String pageCode;
+
+    /**
+     * 涓枃椤甸潰鍚嶇О
+     */
+    private String pageNameCn;
+
+    /**
+     * 椤甸潰鍙傛暟
+     */
+    private String pageParams;
+
+    /**
+     * 杩涘叆椤甸潰鏃堕棿
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date enterTime;
+
+    /**
+     * 绂诲紑椤甸潰鏃堕棿
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date leaveTime;
+
+    /**
+     * 鍋滅暀绉掓暟
+     */
+    private Integer staySeconds;
+
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java b/framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java
index 90b15b1..8caff1e 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java
@@ -1,6 +1,9 @@
 package cn.lili.modules.lmk.mapper;
 
 import cn.lili.modules.lmk.domain.entity.ActionRecord;
+import cn.lili.modules.lmk.domain.query.StayActionRecordQuery;
+import cn.lili.modules.lmk.domain.vo.ShareActionRecordVO;
+import cn.lili.modules.lmk.domain.vo.StayActionRecordVO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import cn.lili.modules.lmk.domain.vo.ActionRecordVO;
@@ -10,6 +13,8 @@
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -36,4 +41,7 @@
 
     BigDecimal getToDayStayTime(@Param("userId") String userId,@Param("begin") LocalDateTime begin ,@Param("end") LocalDateTime end);
 
+    Page<StayActionRecordVO> userStayList(@Param("page") IPage<StayActionRecordVO> page, @Param("req") StayActionRecordQuery param);
+
+    Page<ShareActionRecordVO> userShare(@Param("page") IPage<ShareActionRecordVO> page, @Param("req") StayActionRecordQuery param);
 }
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java b/framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java
index 5012630..c1d4080 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java
@@ -1,6 +1,7 @@
 package cn.lili.modules.lmk.service;
 
 import cn.lili.modules.lmk.domain.entity.ActionRecord;
+import cn.lili.modules.lmk.domain.query.StayActionRecordQuery;
 import com.baomidou.mybatisplus.extension.service.IService;
 import cn.lili.base.Result;
 import cn.lili.modules.lmk.domain.form.ActionRecordForm;
@@ -66,6 +67,10 @@
      */
     Result all();
 
+    Result userStayList(StayActionRecordQuery param);
+
+    Result userShare(StayActionRecordQuery param);
+
     Result grantSessionId();
 
     BigDecimal getToDayStayTime(String userId , LocalDateTime begin , LocalDateTime end);
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java
index 36ea39d..c754f0f 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java
@@ -2,12 +2,17 @@
 
 import cn.lili.common.security.AuthUser;
 import cn.lili.common.security.context.UserContext;
+import cn.lili.modules.lmk.domain.query.StayActionRecordQuery;
+import cn.lili.modules.lmk.domain.vo.ShareActionRecordVO;
+import cn.lili.modules.lmk.domain.vo.StayActionRecordVO;
+import cn.lili.modules.lmk.service.ShareActionService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import cn.lili.modules.lmk.domain.entity.ActionRecord;
 import cn.lili.modules.lmk.mapper.ActionRecordMapper;
 import cn.lili.modules.lmk.service.ActionRecordService;
 import cn.lili.base.Result;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import cn.lili.modules.lmk.domain.form.ActionRecordForm;
 import cn.lili.modules.lmk.domain.vo.ActionRecordVO;
@@ -146,4 +151,18 @@
     public BigDecimal getToDayStayTime(String userId, LocalDateTime begin , LocalDateTime end) {
        return baseMapper.getToDayStayTime(userId,begin,end);
     }
+
+    @Override
+    public Result userStayList(StayActionRecordQuery param) {
+        IPage<StayActionRecordVO> page = PageUtil.getPage(param, StayActionRecordVO.class);
+        Page<StayActionRecordVO> stayActionRecordVOPage = baseMapper.userStayList(page, param);
+        return Result.ok().data(stayActionRecordVOPage);
+    }
+
+    @Override
+    public Result userShare(StayActionRecordQuery param) {
+        IPage<ShareActionRecordVO> page = PageUtil.getPage(param, ShareActionRecordVO.class);
+        Page<ShareActionRecordVO> shareActionRecordVOPage = baseMapper.userShare(page, param);
+        return Result.ok().data(shareActionRecordVOPage);
+    }
 }
\ No newline at end of file
diff --git a/framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml b/framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml
index 12fd549..78ed5f7 100644
--- a/framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml
+++ b/framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml
@@ -85,5 +85,159 @@
                  AND leave_time IS NOT NULL
               ORDER BY user_id, session_id, enter_time) t
     </select>
+    <resultMap id="userStayListMap" type="cn.lili.modules.lmk.domain.vo.StayActionRecordVO">
+        <result property="userId" column="user_id"/>
+        <result property="nickName" column="nick_name"/>
+        <result property="sessionId" column="session_id"/>
+        <result property="pageCode" column="page_code"/>
+        <result property="pageNameCn" column="page_name_cn"/>
+        <result property="enterTime" column="enter_time"/>
+        <result property="leaveTime" column="leave_time"/>
+        <result property="pageParams" column="page_params"/>
+    </resultMap>
+    <select id="userStayList" resultMap="userStayListMap">
+        SELECT
+        t1.user_id,
+        lm.nick_name,
+        t1.session_id,
+        t1.page_params,
+        t1.page_code,
+        CASE t1.page_code
+        WHEN 'RECOMMEND_VIDEO' THEN '棣栭〉鎺ㄨ崘瑙嗛'
+        WHEN 'HEALTH_VIDEO' THEN '澶у仴搴疯棰�'
+        WHEN 'KITCHEN_VIDEO' THEN '绁炲帹瑙嗛'
+        WHEN 'RECOMMEND_VIDEO_GOODS' THEN '瑙嗛鎺ㄨ崘鍟嗗搧椤甸潰'
+        WHEN 'RECOMMEND_VIDEO_LEFT_GOODS' THEN '宸︽粦鎺ㄨ崘鍟嗗搧'
+        WHEN 'RECOMMEND_VIDEO_RIGHT_VIDEO' THEN '鍙虫粦瑙嗛椤甸潰'
+        WHEN 'FILL_ORDER' THEN '濉啓璁㈠崟'
+        WHEN 'PAY_ORDER' THEN '鏀粯璁㈠崟'
+        WHEN 'PAY_SUCCESS' THEN '鏀粯鎴愬姛'
+        WHEN 'ORDER_LIST' THEN '璁㈠崟鍒楄〃'
+        WHEN 'ORDER_DETAIL' THEN '璁㈠崟璇︽儏'
+        WHEN 'PRIZE_DETAIL' THEN '鎶藉娲诲姩'
+        WHEN 'CART_LIST' THEN '璐墿杞�'
+        WHEN 'TBA_BAR_MY' THEN '鎴戠殑椤甸潰'
+        WHEN 'SHOPPING_SQUARE' THEN '鍟嗗搧骞垮満'
+        WHEN 'ACTIVITY_LIST' THEN '娲诲姩鍒楄〃'
+        WHEN 'ACTIVITY_DETAIL' THEN '娲诲姩璇︽儏'
+        WHEN 'PUBLISH_VIDEO' THEN '瑙嗛鍙戝竷'
+        WHEN 'SWIPER_GOODS' THEN '婊戝姩鍟嗗搧'
+        WHEN 'COUPON_CENTER' THEN '棰嗗嵎涓績'
+        WHEN 'MY_COUPON' THEN '鎴戠殑浼樻儬鍗�'
+        WHEN 'AFTER_SALE' THEN '鍞悗鍒楄〃'
+        WHEN 'APPLY_SALE' THEN '鐢宠鍞悗'
+        WHEN 'REFUND_ORDER' THEN '閫�娆�/閫�璐�'
+        WHEN 'GOODS_DETAILS' THEN '鍟嗗搧璇︽儏椤甸潰'
+        ELSE '鏈煡椤甸潰'
+        END AS page_name_cn,
+        t1.start_time AS enter_time,
+        t2.start_time AS leave_time,
+        TIMESTAMPDIFF(SECOND, t1.start_time, t2.start_time) AS stay_seconds
+        FROM
+        lmk_action_record t1
+        JOIN
+        lmk_action_record t2 ON t1.session_id = t2.session_id
+        AND t1.user_id = t2.user_id
+        AND t1.page_code = t2.page_code
+        JOIN li_member lm ON lm.id = t1.user_id
+        WHERE
+        t1.page_status = 'JOIN'
+        AND t2.page_status = 'LEAVE'
+        AND t1.start_time &lt; t2.start_time
+        and t1.start_time between  #{req.beginDate} and #{req.endDate}
+        <if test="req.userName != null and req.userName != ''">
+            and  lm.nick_name like concat('%',#{req.userName},'%')
+        </if>
+        <if test="req.pageCode != null and req.pageCode != ''">
+            and  t1.page_code = #{req.pageCode}
+        </if>
+        ORDER BY
+        t1.user_id,
+        t1.start_time
+    </select>
+    <resultMap id="userShareMap" type="cn.lili.modules.lmk.domain.vo.ShareActionRecordVO">
+        <result property="userId" column="user_id"/>
+        <result property="nickName" column="nick_name"/>
+        <result property="pageCode" column="page_code"/>
+        <result property="pageNameCn" column="page_name_cn"/>
+        <result property="createTime" column="create_time"/>
+        <result property="shareOption" column="share_option"/>
+    </resultMap>
+    <select id="userShare" resultMap="userShareMap">
+        SELECT
+            lm.nick_name,
+            lsa.page_code,
+            lsa.share_option,
+            lsa.user_id,
+            lsa.create_time,
+            CASE
+                lsa.page_code
+                WHEN 'RECOMMEND_VIDEO' THEN
+                    '棣栭〉鎺ㄨ崘瑙嗛'
+                WHEN 'HEALTH_VIDEO' THEN
+                    '澶у仴搴疯棰�'
+                WHEN 'KITCHEN_VIDEO' THEN
+                    '绁炲帹瑙嗛'
+                WHEN 'RECOMMEND_VIDEO_GOODS' THEN
+                    '瑙嗛鎺ㄨ崘鍟嗗搧椤甸潰'
+                WHEN 'RECOMMEND_VIDEO_LEFT_GOODS' THEN
+                    '宸︽粦鎺ㄨ崘鍟嗗搧'
+                WHEN 'RECOMMEND_VIDEO_RIGHT_VIDEO' THEN
+                    '鍙虫粦瑙嗛椤甸潰'
+                WHEN 'FILL_ORDER' THEN
+                    '濉啓璁㈠崟'
+                WHEN 'PAY_ORDER' THEN
+                    '鏀粯璁㈠崟'
+                WHEN 'PAY_SUCCESS' THEN
+                    '鏀粯鎴愬姛'
+                WHEN 'ORDER_LIST' THEN
+                    '璁㈠崟鍒楄〃'
+                WHEN 'ORDER_DETAIL' THEN
+                    '璁㈠崟璇︽儏'
+                WHEN 'PRIZE_DETAIL' THEN
+                    '鎶藉娲诲姩'
+                WHEN 'CART_LIST' THEN
+                    '璐墿杞�'
+                WHEN 'TBA_BAR_MY' THEN
+                    '鎴戠殑椤甸潰'
+                WHEN 'SHOPPING_SQUARE' THEN
+                    '鍟嗗搧骞垮満'
+                WHEN 'ACTIVITY_LIST' THEN
+                    '娲诲姩鍒楄〃'
+                WHEN 'ACTIVITY_DETAIL' THEN
+                    '娲诲姩璇︽儏'
+                WHEN 'PUBLISH_VIDEO' THEN
+                    '瑙嗛鍙戝竷'
+                WHEN 'SWIPER_GOODS' THEN
+                    '婊戝姩鍟嗗搧'
+                WHEN 'COUPON_CENTER' THEN
+                    '棰嗗嵎涓績'
+                WHEN 'MY_COUPON' THEN
+                    '鎴戠殑浼樻儬鍗�'
+                WHEN 'AFTER_SALE' THEN
+                    '鍞悗鍒楄〃'
+                WHEN 'APPLY_SALE' THEN
+                    '鐢宠鍞悗'
+                WHEN 'REFUND_ORDER' THEN
+                    '閫�娆�/閫�璐�'
+                WHEN 'GOODS_DETAILS' THEN
+                    '鍟嗗搧璇︽儏椤甸潰' ELSE '鏈煡椤甸潰'
+                END AS page_name_cn
+        FROM
+            lmk_share_action lsa
+                JOIN li_member lm ON lsa.user_id = lm.id
+        WHERE
+            lsa.delete_flag = 0
+          AND lm.delete_flag = 0
+        and lsa.create_time between  #{req.beginDate} and #{req.endDate}
+        <if test="req.userName != null and req.userName != ''">
+            and  lm.nick_name like concat('%',#{req.userName},'%')
+        </if>
+        <if test="req.pageCode != null and req.pageCode != ''">
+            and  lsa.page_code = #{req.pageCode}
+        </if>
+        ORDER BY
+        lsa.create_time desc
+    </select>
 
 </mapper>
diff --git a/manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java b/manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java
index 22d40df..131efe1 100644
--- a/manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java
+++ b/manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java
@@ -2,6 +2,7 @@
 
 import cn.lili.group.Update;
 import cn.lili.group.Add;
+import cn.lili.modules.lmk.domain.query.StayActionRecordQuery;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.security.access.prepost.PreAuthorize;
 import lombok.RequiredArgsConstructor;
@@ -73,4 +74,14 @@
     public Result list() {
         return actionRecordService.all();
     }
+    @GetMapping("/userStayList")
+    @ApiOperation(value = "鐢ㄦ埛椤甸潰鍋滅暀淇℃伅", notes = "鐢ㄦ埛椤甸潰鍋滅暀淇℃伅")
+    public Result userStayList(StayActionRecordQuery param) {
+        return actionRecordService.userStayList(param);
+    }
+    @GetMapping("/userShare")
+    @ApiOperation(value = "鐢ㄦ埛鍒嗕韩", notes = "鐢ㄦ埛鍒嗕韩")
+    public Result userShare(StayActionRecordQuery param) {
+        return actionRecordService.userShare(param);
+    }
 }

--
Gitblit v1.8.0