为 alien-store 模块的用户端实现完整的埋点系统,用于统计和分析用户行为数据,并通过AI提供智能推荐服务。
根据原型图,需要收集以下类型的数据:
前端 (客户端)
↓ HTTP请求 / WebSocket消息
Controller / WebSocketProcess (埋点触发)
↓ 异步写入
Redis List (消息队列)
↓ 定时任务批量消费
数据库 (MySQL)
↓ 统计分析
统计查询接口
↓ AI分析
AI推荐服务
@TrackEvent): 标注需要埋点的HTTP接口方法TrackEventAspect): 拦截标注的方法,自动收集数据WebSocketProcess): 处理WebSocket消息时触发埋点TrackEventConsumer): 定时从Redis List批量消费数据并写入数据库TrackEventController): 提供前端主动上报埋点和手动触发统计的接口BusinessDataController): 提供经营数据统计查询AIRecoveryController): 基于埋点数据提供AI推荐系统支持三种埋点方式:
| 方式 | 说明 | 适用场景 |
|---|---|---|
@TrackEvent注解 |
AOP自动拦截,无侵入式 | 标准HTTP接口 |
| WebSocket埋点 | 在WebSocket消息处理中主动记录 | 实时消息场景(咨询、分享) |
| 前端主动上报 | 通过/track/event接口上报 |
前端特有行为(浏览时长等) |
CREATE TABLE `store_track_event` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_type` varchar(50) NOT NULL COMMENT '事件类型(VIEW-浏览,SEARCH-搜索,COLLECT-收藏,SHARE-分享,CHECKIN-打卡,CONSULT-咨询,FOLLOW-关注,UNFOLLOW-取消关注,FRIEND_ADD-添加好友,POST_PUBLISH-发布动态,POST_LIKE-动态点赞,POST_COMMENT-动态评论,POST_REPOST-动态转发,REPORT-举报,BLOCK-拉黑,COUPON_GIVE-赠送优惠券,COUPON_USE-使用优惠券,VOUCHER_GIVE-赠送代金券,VOUCHER_USE-使用代金券,PRICE_VIEW-价目表浏览,PRICE_SHARE-价目表分享,RATING-评价,APPEAL-申诉)',
`event_category` varchar(50) NOT NULL COMMENT '事件分类(TRAFFIC-流量数据,INTERACTION-互动数据,COUPON-优惠券,VOUCHER-代金券,SERVICE-服务质量,PRICE-价目表)',
`user_id` int(11) DEFAULT NULL COMMENT '用户ID',
`store_id` int(11) DEFAULT NULL COMMENT '店铺ID',
`target_id` int(11) DEFAULT NULL COMMENT '目标对象ID(如价目表ID、动态ID等)',
`target_type` varchar(50) DEFAULT NULL COMMENT '目标对象类型(PRICE-价目表,POST-动态,STORE-店铺等)',
`event_data` text COMMENT '事件附加数据(JSON格式)',
`amount` decimal(10,2) DEFAULT NULL COMMENT '金额(用于优惠券、代金券等)',
`duration` bigint(20) DEFAULT NULL COMMENT '时长(毫秒,用于访问时长等)',
`ip_address` varchar(50) DEFAULT NULL COMMENT 'IP地址',
`user_agent` varchar(500) DEFAULT NULL COMMENT '用户代理',
`device_type` varchar(20) DEFAULT NULL COMMENT '设备类型(IOS,ANDROID,WEB)',
`app_version` varchar(20) DEFAULT NULL COMMENT 'APP版本号',
`event_time` datetime NOT NULL COMMENT '事件发生时间',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`delete_flag` int(1) NOT NULL DEFAULT '0' COMMENT '删除标记(0:未删除,1:已删除)',
PRIMARY KEY (`id`),
KEY `idx_store_id` (`store_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_event_type` (`event_type`),
KEY `idx_event_category` (`event_category`),
KEY `idx_event_time` (`event_time`),
KEY `idx_store_event_time` (`store_id`,`event_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='埋点事件表';
用于存储按店铺、日期聚合的统计数据,提升查询性能:
CREATE TABLE `store_track_statistics` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`store_id` int(11) NOT NULL COMMENT '店铺ID',
`stat_date` date NOT NULL COMMENT '统计日期',
`stat_type` varchar(50) NOT NULL COMMENT '统计类型(DAILY-日统计,WEEKLY-周统计,MONTHLY-月统计)',
`traffic_data` text COMMENT '流量数据(JSON格式)',
`interaction_data` text COMMENT '互动数据(JSON格式)',
`coupon_data` text COMMENT '优惠券数据(JSON格式)',
`voucher_data` text COMMENT '代金券数据(JSON格式)',
`service_data` text COMMENT '服务质量数据(JSON格式)',
`price_ranking_data` text COMMENT '价目表排名数据(JSON格式)',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_store_date_type` (`store_id`,`stat_date`,`stat_type`),
KEY `idx_store_id` (`store_id`),
KEY `idx_stat_date` (`stat_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='埋点统计表';
定义在 alien-store/src/main/java/shop/alien/store/annotation/TrackEvent.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TrackEvent {
String eventType(); // 事件类型
String eventCategory(); // 事件分类
String storeId() default ""; // 店铺ID的SpEL表达式
String targetId() default ""; // 目标对象ID的SpEL表达式
String targetType() default "";// 目标对象类型
String userId() default ""; // 用户ID的SpEL表达式
boolean async() default true; // 是否异步执行
}
定义在 alien-store/src/main/java/shop/alien/store/aspect/TrackEventAspect.java
主要功能:
@TrackEvent注解的方法定义在 alien-store/src/main/java/shop/alien/store/config/WebSocketProcess.java
支持的WebSocket埋点:
| 事件类型 | 触发条件 | 说明 |
|---|---|---|
| CONSULT | receiverId以store_开头的普通消息 |
用户咨询店铺 |
| SHARE | 消息type为"3"(链接分享)或"14"(人员分享) | 用户分享店铺 |
WebSocket配置:
WebSocketConfig.java: 配置WebSocket并提供自定义ConfiguratorWebSocketConfigurator: 在握手阶段获取IP地址和User-Agent使用现有的 BaseRedisService 的 setListRight 方法将埋点数据写入Redis List
Redis Key:
track:event:queuetrack:event:consumer:lock定义在 alien-store/src/main/java/shop/alien/store/service/TrackEventConsumer.java
使用 @Scheduled 注解定时从Redis List批量取出数据并写入数据库
消费策略:
定义在 alien-store/src/main/java/shop/alien/store/controller/TrackEventController.java
| 接口路径 | 方法名 | 事件类型 |
|---|---|---|
/aiSearch/search |
search | SEARCH |
| 接口路径 | 方法名 | 事件类型 |
|---|---|---|
/collect/addCollect |
addCollect | COLLECT |
/storeClockIn/addStoreClockIn |
addStoreClockIn | CHECKIN |
/renovation/requirement/consultRequirement |
consultRequirement | CONSULT |
/userDynamics/addOrUpdate |
addOrUpdate | POST_PUBLISH |
/userDynamics/addTransferCount |
addTransferCount | POST_REPOST |
/comment/like |
like | POST_LIKE |
/commonComment/addComment |
addComment | POST_COMMENT |
/user-violation/reporting |
reporting | REPORT |
/life-blacklist/blackList |
blackList | BLOCK |
| 接口路径 | 方法名 | 事件类型 |
|---|---|---|
/commonRating/addRating |
add | RATING_ADD |
/storeCommentAppeal/addAppealNew |
addAppealNew | APPEAL |
| 接口路径 | 方法名 | 事件类型 |
|---|---|---|
/store/price/getById |
getById | PRICE_VIEW |
/store/cuisine/getByCuisineType |
getByCuisineType | PRICE_VIEW |
| 接口路径 | 方法名 | 事件类型 |
|---|---|---|
/life-discount-coupon-store-friend/setFriendCoupon |
setFriendCoupon | COUPON_GIVE |
/coupon/verify |
verify | COUPON_USE |
| 触发场景 | 消息类型 | 事件类型 | 说明 |
|---|---|---|---|
| 用户咨询店铺 | WebSocket消息 | CONSULT | receiverId以store_开头时触发 |
| 用户分享店铺 | type="3"或"14" | SHARE | 从消息内容中解析storeId |
接口路径: POST /track/event
接口说明: 前端主动上报埋点数据
请求参数:
{
"eventType": "VIEW",
"eventCategory": "TRAFFIC",
"storeId": 1001,
"targetId": 2001,
"targetType": "PRICE",
"eventData": "{}",
"amount": 100.00,
"duration": 3000
}
响应示例:
{
"code": 200,
"success": true,
"msg": "上报成功",
"data": null
}
接口路径: POST /track/statistics/calculate
接口说明: 手动触发统计数据计算
请求参数:
storeId: 店铺ID (必填)statDate: 统计日期 (格式: yyyy-MM-dd)statType: 统计类型 (DAILY/WEEKLY/MONTHLY)响应示例:
{
"code": 200,
"success": true,
"msg": "统计数据计算成功",
"data": null
}
public enum EventType {
// 流量数据
VIEW("VIEW", "浏览"),
SEARCH("SEARCH", "搜索"),
// 互动数据
COLLECT("COLLECT", "收藏"),
SHARE("SHARE", "分享"),
CHECKIN("CHECKIN", "打卡"),
CONSULT("CONSULT", "咨询"),
FOLLOW("FOLLOW", "关注"),
UNFOLLOW("UNFOLLOW", "取消关注"),
FRIEND_ADD("FRIEND_ADD", "添加好友"),
POST_PUBLISH("POST_PUBLISH", "发布动态"),
POST_LIKE("POST_LIKE", "动态点赞"),
POST_COMMENT("POST_COMMENT", "动态评论"),
POST_REPOST("POST_REPOST", "动态转发"),
REPORT("REPORT", "举报"),
BLOCK("BLOCK", "拉黑"),
// 优惠券
COUPON_GIVE("COUPON_GIVE", "赠送优惠券"),
COUPON_USE("COUPON_USE", "使用优惠券"),
// 代金券
VOUCHER_GIVE("VOUCHER_GIVE", "赠送代金券"),
VOUCHER_USE("VOUCHER_USE", "使用代金券"),
// 价目表
PRICE_VIEW("PRICE_VIEW", "价目表浏览"),
PRICE_SHARE("PRICE_SHARE", "价目表分享"),
// 服务质量
RATING_ADD("RATING_ADD", "添加评价"),
APPEAL("APPEAL", "申诉");
}
| 数据类型 | 统计规则 | 说明 |
|---|---|---|
| 大部分数据 | 累计统计 | 统计截止到统计日期的所有数据 |
| 新增访客数 | 增量统计 | 统计周期内的新增访客(排除之前访问过的用户) |
| 统计类型 | 开始时间 | 结束时间 |
|---|---|---|
| DAILY | statDate 00:00:00 | statDate+1 00:00:00 |
| WEEKLY | statDate所在周的周一 00:00:00 | 周日+1 00:00:00 |
| MONTHLY | statDate所在月的1号 00:00:00 | 下月1号 00:00:00 |
确保pom.xml中配置了-parameters参数,以保留方法参数名称(SpEL表达式需要):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<parameters>true</parameters>
</configuration>
</plugin>
文档版本:v2.0
最后更新:2026-01-24