peng
2025-10-15 c40f30d375d4108c8514eed49b372cbb7d80bb57
用户行为分析
5个文件已修改
3个文件已添加
358 ■■■■■ 已修改文件
framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/query/StayActionRecordQuery.java
New file
@@ -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;
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionRecordVO.java
New file
@@ -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;
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/StayActionRecordVO.java
New file
@@ -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;
}
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);
}
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);
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);
    }
}
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>
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);
    }
}