peng
2025-09-08 35d33220697854e622c6e3d39c18ce9ef2537320
初始化用户行为分析
11个文件已添加
672 ■■■■■ 已修改文件
buyer-api/src/main/java/cn/lili/controller/lmk/ActionRecordBuyerController.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/entity/ActionRecord.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/form/ActionRecordForm.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/query/ActionRecordQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/ActionRecordVO.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageEnums.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/java/cn/lili/controller/lmk/ActionRecordBuyerController.java
New file
@@ -0,0 +1,42 @@
package cn.lili.controller.lmk;
import cn.lili.group.Update;
import cn.lili.group.Add;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import cn.lili.modules.lmk.service.ActionRecordService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
 * 用户行为记录 前端控制器
 *
 * @author peng
 * @since 2025-09-08
 */
@Validated
@RequiredArgsConstructor
@Api(value = "用户行为记录", tags = "用户行为记录管理")
@RestController
@RequestMapping("/buyer/lmk/action-record")
public class ActionRecordBuyerController {
    private final ActionRecordService actionRecordService;
    @PostMapping
    @ApiOperation(value = "添加", notes = "添加")
    public Result add(@RequestBody @Validated(Add.class) ActionRecordForm form) {
        return actionRecordService.add(form);
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/entity/ActionRecord.java
New file
@@ -0,0 +1,67 @@
package cn.lili.modules.lmk.domain.entity;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
 * 用户行为记录
 *
 * @author peng
 * @since 2025-09-08
 */
@Data
@TableName("lmk_action_record")
public class ActionRecord extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableField("user_id")
    /** 用户id */
    private Long userId;
    @TableField("session_id")
    /** 页面会话id */
    private String sessionId;
    @TableField("action_type")
    /** 行为类型 */
    private String actionType;
    @TableField("start_time")
    /** 触发时间 */
    private LocalDateTime startTime;
    @TableField("join_type")
    /** 进入页面方式 */
    private String joinType;
    @TableField("previous_session_id")
    /** 上一个页面的会话id */
    private String previousSessionId;
    @TableField("share_id")
    /** 分享id */
    private Long shareId;
    @TableField("page_code")
    /** 页面编码 */
    private String pageCode;
    @TableField("page_params")
    /** 页面详情参数(json格式) */
    private String pageParams;
    @TableField("page_type")
    /** 页面类型 */
    private String pageType;
    @TableField("page_status")
    /** 用户在页面状态 */
    private String pageStatus;
}
framework/src/main/java/cn/lili/modules/lmk/domain/form/ActionRecordForm.java
New file
@@ -0,0 +1,78 @@
package cn.lili.modules.lmk.domain.form;
import cn.lili.group.Update;
import cn.lili.group.Add;
import cn.lili.base.AbsForm;
import cn.lili.modules.lmk.domain.entity.ActionRecord;
import org.springframework.beans.BeanUtils;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.springframework.lang.NonNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * 用户行为记录表单
 *
 * @author peng
 * @since 2025-09-08
 */
@Data
@ApiModel(value = "ActionRecord表单", description = "用户行为记录表单")
public class ActionRecordForm extends AbsForm {
    @NotNull(message = "用户id不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("用户id")
    private Long userId;
    @NotBlank(message = "页面会话id不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面会话id")
    private String sessionId;
    @NotBlank(message = "行为类型不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("行为类型")
    private String actionType;
    @NotNull(message = "触发时间不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("触发时间")
    private Date startTime;
    @NotBlank(message = "进入页面方式不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("进入页面方式")
    private String joinType;
    @NotBlank(message = "上一个页面的会话id不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("上一个页面的会话id")
    private String previousSessionId;
    @NotNull(message = "分享id不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("分享id")
    private Long shareId;
    @NotBlank(message = "页面编码不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面编码")
    private String pageCode;
    @NotBlank(message = "页面详情参数(json格式)不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面详情参数(json格式)")
    private String pageParams;
    @NotBlank(message = "页面类型不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面类型")
    private String pageType;
    @NotBlank(message = "用户在页面状态不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("用户在页面状态")
    private String pageStatus;
    public static ActionRecord getEntityByForm(@NonNull ActionRecordForm form, ActionRecord entity) {
        if(entity == null) {
          entity = new ActionRecord();
        }
        BeanUtils.copyProperties(form, entity);
        return entity;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/query/ActionRecordQuery.java
New file
@@ -0,0 +1,22 @@
package cn.lili.modules.lmk.domain.query;
import cn.lili.base.AbsQuery;
import java.util.List;
import org.springframework.lang.NonNull;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * 用户行为记录查询
 *
 * @author peng
 * @since 2025-09-08
 */
@Data
@ApiModel(value = "ActionRecord查询参数", description = "用户行为记录查询参数")
public class ActionRecordQuery extends AbsQuery {
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/ActionRecordVO.java
New file
@@ -0,0 +1,75 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.ActionRecord;
import java.util.List;
import org.springframework.lang.NonNull;
import org.springframework.beans.BeanUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * 用户行为记录展示
 *
 * @author peng
 * @since 2025-09-08
 */
@Data
@ApiModel(value = "用户行为记录响应数据", description = "用户行为记录响应数据")
public class ActionRecordVO extends AbsVo {
    /** 用户id */
    @ApiModelProperty("用户id")
    private Long userId;
    /** 页面会话id */
    @ApiModelProperty("页面会话id")
    private String sessionId;
    /** 行为类型 */
    @ApiModelProperty("行为类型")
    private String actionType;
    /** 触发时间 */
    @ApiModelProperty("触发时间")
    private Date startTime;
    /** 进入页面方式 */
    @ApiModelProperty("进入页面方式")
    private String joinType;
    /** 上一个页面的会话id */
    @ApiModelProperty("上一个页面的会话id")
    private String previousSessionId;
    /** 分享id */
    @ApiModelProperty("分享id")
    private Long shareId;
    /** 页面编码 */
    @ApiModelProperty("页面编码")
    private String pageCode;
    /** 页面详情参数(json格式) */
    @ApiModelProperty("页面详情参数(json格式)")
    private String pageParams;
    /** 页面类型 */
    @ApiModelProperty("页面类型")
    private String pageType;
    /** 用户在页面状态 */
    @ApiModelProperty("用户在页面状态")
    private String pageStatus;
    public static ActionRecordVO getVoByEntity(@NonNull ActionRecord entity, ActionRecordVO vo) {
        if(vo == null) {
            vo = new ActionRecordVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageEnums.java
New file
@@ -0,0 +1,26 @@
package cn.lili.modules.lmk.enums.general;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum UserActionPageEnums {
    RECOMMEND_VIDEO("首页推荐视频"),
    HEALTH_VIDEO("大健康视频"),
    KITCHEN_VIDEO("神厨视频"),
    RECOMMEND_VIDEO_GOODS("视频推荐商品页面"),
    RECOMMEND_VIDEO_LEFT_GOODS("左滑推荐商品"),
    RECOMMEND_VIDEO_RIGHT_VIDEO("右滑视频页面"),
    ACTIVITY("活动"),
    SHOPPING_SQUARE("商品广场"),
    GOODS_DETAILS("商品详情页面");
    private final String des;
    public UserActionPageEnums select(String name){
        for (UserActionPageEnums value : UserActionPageEnums.values()) {
            if (value.name().equals(name)) {
                return value;
            }
        }
        return null;
    }
}
framework/src/main/java/cn/lili/modules/lmk/mapper/ActionRecordMapper.java
New file
@@ -0,0 +1,34 @@
package cn.lili.modules.lmk.mapper;
import cn.lili.modules.lmk.domain.entity.ActionRecord;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.lili.modules.lmk.domain.vo.ActionRecordVO;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * 用户行为记录 Mapper 接口
 *
 * @author peng
 * @since 2025-09-08
 */
@Mapper
public interface ActionRecordMapper extends BaseMapper<ActionRecord> {
    /**
     * id查找用户行为记录
     * @param id
     * @return
     */
    ActionRecordVO getById(String id);
    /**
    *  分页
    */
    IPage getPage(IPage page, @Param("query") ActionRecordQuery query);
}
framework/src/main/java/cn/lili/modules/lmk/service/ActionRecordService.java
New file
@@ -0,0 +1,65 @@
package cn.lili.modules.lmk.service;
import cn.lili.modules.lmk.domain.entity.ActionRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import java.util.List;
/**
 * 用户行为记录 服务类
 *
 * @author peng
 * @since 2025-09-08
 */
public interface ActionRecordService extends IService<ActionRecord> {
    /**
     * 添加
     * @param form
     * @return
     */
    Result add(ActionRecordForm form);
    /**
     * 修改
     * @param form
     * @return
     */
    Result update(ActionRecordForm form);
    /**
     * 批量删除
     * @param ids
     * @return
     */
    Result remove(List<String> ids);
    /**
     * id删除
     * @param id
     * @return
     */
    Result removeById(String id);
    /**
     * 分页查询
     * @param query
     * @return
     */
    Result page(ActionRecordQuery query);
    /**
     * 根据id查找
     * @param id
     * @return
     */
    Result detail(String id);
    /**
     * 列表
     * @return
     */
    Result all();
}
framework/src/main/java/cn/lili/modules/lmk/service/impl/ActionRecordServiceImpl.java
New file
@@ -0,0 +1,119 @@
package cn.lili.modules.lmk.service.impl;
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.extension.service.impl.ServiceImpl;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.vo.ActionRecordVO;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import cn.lili.utils.PageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 用户行为记录 服务实现类
 *
 * @author peng
 * @since 2025-09-08
 */
@Service
@RequiredArgsConstructor
public class ActionRecordServiceImpl extends ServiceImpl<ActionRecordMapper, ActionRecord> implements ActionRecordService {
    private final ActionRecordMapper actionRecordMapper;
    /**
     * 添加
     * @param form
     * @return
     */
    @Override
    public Result add(ActionRecordForm form) {
        ActionRecord entity = ActionRecordForm.getEntityByForm(form, null);
        baseMapper.insert(entity);
        return Result.ok("添加成功");
    }
    /**
     * 修改
     * @param form
     * @return
     */
    @Override
    public Result update(ActionRecordForm form) {
        ActionRecord entity = baseMapper.selectById(form.getId());
        // 为空抛IllegalArgumentException,做全局异常处理
        Assert.notNull(entity, "记录不存在");
        BeanUtils.copyProperties(form, entity);
        baseMapper.updateById(entity);
        return Result.ok("修改成功");
    }
    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public Result remove(List<String> ids) {
        baseMapper.deleteBatchIds(ids);
        return Result.ok("删除成功");
    }
    /**
     * id删除
     * @param id
     * @return
     */
    @Override
    public Result removeById(String id) {
        baseMapper.deleteById(id);
        return Result.ok("删除成功");
    }
    /**
     * 分页查询
     * @param query
     * @return
     */
    @Override
    public Result page(ActionRecordQuery query) {
        IPage<ActionRecordVO> page = PageUtil.getPage(query, ActionRecordVO.class);
        baseMapper.getPage(page, query);
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 根据id查找
     * @param id
     * @return
     */
    @Override
    public Result detail(String id) {
        ActionRecordVO vo = baseMapper.getById(id);
        Assert.notNull(vo, "记录不存在");
        return Result.ok().data(vo);
    }
    /**
     * 列表
     * @return
     */
    @Override
    public Result all() {
        List<ActionRecord> entities = baseMapper.selectList(null);
        List<ActionRecordVO> vos = entities.stream()
                .map(entity -> ActionRecordVO.getVoByEntity(entity, null))
                .collect(Collectors.toList());
        return Result.ok().data(vos);
    }
}
framework/src/main/resources/mapper/lmk/ActionRecordMapper.xml
New file
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.lili.modules.lmk.mapper.ActionRecordMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="cn.lili.modules.lmk.domain.vo.ActionRecordVO">
        <id column="id" property="id"/>
        <result column="user_id" property="userId" />
        <result column="session_id" property="sessionId" />
        <result column="action_type" property="actionType" />
        <result column="start_time" property="startTime" />
        <result column="join_type" property="joinType" />
        <result column="previous_session_id" property="previousSessionId" />
        <result column="share_id" property="shareId" />
        <result column="page_code" property="pageCode" />
        <result column="page_params" property="pageParams" />
        <result column="page_type" property="pageType" />
        <result column="page_status" property="pageStatus" />
    </resultMap>
    <select id="getById" resultMap="BaseResultMap">
        SELECT
            LAR.user_id,
            LAR.session_id,
            LAR.action_type,
            LAR.start_time,
            LAR.join_type,
            LAR.previous_session_id,
            LAR.share_id,
            LAR.page_code,
            LAR.page_params,
            LAR.page_type,
            LAR.page_status,
            LAR.id
        FROM
            lmk_action_record LAR
        WHERE
            LAR.id = #{id} AND LAR.delete_flag = 0
    </select>
    <select id="getPage" resultMap="BaseResultMap">
        SELECT
            LAR.user_id,
            LAR.session_id,
            LAR.action_type,
            LAR.start_time,
            LAR.join_type,
            LAR.previous_session_id,
            LAR.share_id,
            LAR.page_code,
            LAR.page_params,
            LAR.page_type,
            LAR.page_status,
            LAR.id
        FROM
            lmk_action_record LAR
        WHERE
            LAR.delete_flag = 0
    </select>
</mapper>
manager-api/src/main/java/cn/lili/controller/lmk/ActionRecordManagerController.java
New file
@@ -0,0 +1,76 @@
package cn.lili.controller.lmk;
import cn.lili.group.Update;
import cn.lili.group.Add;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import cn.lili.modules.lmk.service.ActionRecordService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
 * 用户行为记录 前端控制器
 *
 * @author peng
 * @since 2025-09-08
 */
@Validated
@RequiredArgsConstructor
@Api(value = "用户行为记录", tags = "用户行为记录管理")
@RestController
@RequestMapping("/manager/lmk/action-record")
public class ActionRecordManagerController {
    private final ActionRecordService actionRecordService;
    @PostMapping
    @ApiOperation(value = "添加", notes = "添加")
    public Result add(@RequestBody @Validated(Add.class) ActionRecordForm form) {
        return actionRecordService.add(form);
    }
    @PutMapping
    @ApiOperation(value = "修改", notes = "修改")
    public Result update(@RequestBody @Validated(Update.class) ActionRecordForm form) {
        return actionRecordService.update(form);
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "ID删除", notes = "ID删除")
    public Result removeById(@PathVariable("id") String id) {
        return actionRecordService.removeById(id);
    }
    @DeleteMapping("/batch")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    public Result remove(@RequestBody @NotEmpty(message = "请选择数据") List<String> ids) {
        return actionRecordService.remove(ids);
    }
    @GetMapping("/page")
    @ApiOperation(value = "分页", notes = "分页")
    public Result page(ActionRecordQuery query) {
        return actionRecordService.page(query);
    }
    @GetMapping("/{id}")
    @ApiOperation(value = "详情", notes = "详情")
    public Result detail(@PathVariable("id") String id) {
        return actionRecordService.detail(id);
    }
    @GetMapping("/list")
    @ApiOperation(value = "列表", notes = "列表")
    public Result list() {
        return actionRecordService.all();
    }
}