# 用户端埋点需求完整方案文档 ## 一、需求概述 为 alien-store 模块的用户端实现完整的埋点系统,用于统计和分析用户行为数据,并通过AI提供智能推荐服务。 ### 1.1 埋点数据类型 根据原型图,需要收集以下类型的数据: #### 1.1.1 流量数据 - 店铺搜索量 - 浏览量 - 访客数 - 新增访客数 - 访问时长 - 平均访问时长 #### 1.1.2 互动数据 - 店铺收藏次数 - 店铺分享次数 - 店铺打卡次数 - 咨询商家次数 - 好友数量 - 关注数量 - 粉丝数量 - 发布动态数量 - 动态点赞数量 - 动态评论数量 - 动态转发数量 - 被举报次数 - 被拉黑次数 #### 1.1.3 优惠券数据 - 赠送好友数量 - 赠送好友金额合计 - 赠送好友使用数量 - 赠送好友使用金额合计 - 赠送好友使用金额占比 - 好友赠送数量 - 好友赠送金额合计 - 好友赠送使用数量 - 好友赠送使用金额合计 - 好友赠送使用金额占比 #### 1.1.4 代金券数据 - 赠送好友数量 - 赠送好友金额合计 - 赠送好友使用数量 - 赠送好友使用金额合计 - 赠送好友使用金额占比 - 好友赠送数量 - 好友赠送金额合计 - 好友赠送使用数量 - 好友赠送使用金额合计 - 好友赠送使用金额占比 #### 1.1.5 服务质量数据 - 店铺评分 - 评分1 - 评分2 - 评分3 - 评价数量 - 好评数量 - 中评数量 - 差评数量 - 差评占比 - 差评申诉次数 - 差评申诉成功次数 - 差评申诉成功占比 #### 1.1.6 价目表排名数据 - 价目表浏览量 - 价目表访客数 - 价目表分享数 ## 二、技术架构 ### 2.1 架构设计 ``` 前端 (客户端) ↓ HTTP请求 / WebSocket消息 Controller / WebSocketProcess (埋点触发) ↓ 异步写入 Redis List (消息队列) ↓ 定时任务批量消费 数据库 (MySQL) ↓ 统计分析 统计查询接口 ↓ AI分析 AI推荐服务 ``` ### 2.2 核心组件 1. **埋点注解** (`@TrackEvent`): 标注需要埋点的HTTP接口方法 2. **AOP切面** (`TrackEventAspect`): 拦截标注的方法,自动收集数据 3. **WebSocket处理** (`WebSocketProcess`): 处理WebSocket消息时触发埋点 4. **Redis List**: 作为消息队列,异步存储埋点数据 5. **消费服务** (`TrackEventConsumer`): 定时从Redis List批量消费数据并写入数据库 6. **前端接口** (`TrackEventController`): 提供前端主动上报埋点和手动触发统计的接口 7. **统计接口** (`BusinessDataController`): 提供经营数据统计查询 8. **AI推荐接口** (`AIRecoveryController`): 基于埋点数据提供AI推荐 ### 2.3 埋点方式 系统支持三种埋点方式: | 方式 | 说明 | 适用场景 | |-----|------|---------| | `@TrackEvent`注解 | AOP自动拦截,无侵入式 | 标准HTTP接口 | | WebSocket埋点 | 在WebSocket消息处理中主动记录 | 实时消息场景(咨询、分享) | | 前端主动上报 | 通过`/track/event`接口上报 | 前端特有行为(浏览时长等) | ## 三、数据库表设计 ### 3.1 埋点事件主表 (store_track_event) ```sql 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='埋点事件表'; ``` ### 3.2 埋点统计数据表 (store_track_statistics) 用于存储按店铺、日期聚合的统计数据,提升查询性能: ```sql 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='埋点统计表'; ``` ## 四、后端实现 ### 4.1 埋点注解 (@TrackEvent) 定义在 `alien-store/src/main/java/shop/alien/store/annotation/TrackEvent.java` ```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; // 是否异步执行 } ``` ### 4.2 AOP切面实现 定义在 `alien-store/src/main/java/shop/alien/store/aspect/TrackEventAspect.java` **主要功能**: - 拦截带有`@TrackEvent`注解的方法 - 使用SpEL表达式从方法参数或返回值中提取数据 - 自动获取IP地址、User-Agent、设备类型等信息 - 支持业务逻辑兜底查询storeId(适用于SpEL无法直接获取的场景) ### 4.3 WebSocket埋点实现 定义在 `alien-store/src/main/java/shop/alien/store/config/WebSocketProcess.java` **支持的WebSocket埋点**: | 事件类型 | 触发条件 | 说明 | |---------|---------|------| | CONSULT | receiverId以`store_`开头的普通消息 | 用户咨询店铺 | | SHARE | 消息type为"3"(链接分享)或"14"(人员分享) | 用户分享店铺 | **WebSocket配置**: - `WebSocketConfig.java`: 配置WebSocket并提供自定义Configurator - `WebSocketConfigurator`: 在握手阶段获取IP地址和User-Agent ### 4.4 Redis List 异步存储 使用现有的 `BaseRedisService` 的 `setListRight` 方法将埋点数据写入Redis List **Redis Key**: - 埋点队列: `track:event:queue` - 消费锁: `track:event:consumer:lock` ### 4.5 定时任务消费 定义在 `alien-store/src/main/java/shop/alien/store/service/TrackEventConsumer.java` 使用 `@Scheduled` 注解定时从Redis List批量取出数据并写入数据库 **消费策略**: - 消费频率: 每10秒执行一次 - 使用分布式锁防止多实例重复消费 - 批量保存到数据库 ### 4.6 前端上报接口 定义在 `alien-store/src/main/java/shop/alien/store/controller/TrackEventController.java` ## 五、埋点接口清单 ### 5.1 HTTP接口埋点(16个) #### 流量数据(TRAFFIC)- 1个 | 接口路径 | 方法名 | 事件类型 | |---------|--------|---------| | `/aiSearch/search` | search | SEARCH | #### 互动数据(INTERACTION)- 9个 | 接口路径 | 方法名 | 事件类型 | |---------|--------|---------| | `/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 | #### 服务质量(SERVICE)- 2个 | 接口路径 | 方法名 | 事件类型 | |---------|--------|---------| | `/commonRating/addRating` | add | RATING_ADD | | `/storeCommentAppeal/addAppealNew` | addAppealNew | APPEAL | #### 价目表(PRICE)- 2个 | 接口路径 | 方法名 | 事件类型 | |---------|--------|---------| | `/store/price/getById` | getById | PRICE_VIEW | | `/store/cuisine/getByCuisineType` | getByCuisineType | PRICE_VIEW | #### 优惠券(COUPON)- 2个 | 接口路径 | 方法名 | 事件类型 | |---------|--------|---------| | `/life-discount-coupon-store-friend/setFriendCoupon` | setFriendCoupon | COUPON_GIVE | | `/coupon/verify` | verify | COUPON_USE | ### 5.2 WebSocket埋点(2个) | 触发场景 | 消息类型 | 事件类型 | 说明 | |---------|---------|---------|------| | 用户咨询店铺 | WebSocket消息 | CONSULT | receiverId以store_开头时触发 | | 用户分享店铺 | type="3"或"14" | SHARE | 从消息内容中解析storeId | ### 5.3 统计汇总 - **总埋点数**: 18个 - **HTTP接口**: 16个 - **WebSocket埋点**: 2个 ## 六、前端联调 ### 6.1 前端主动调用埋点上报接口 **接口路径**: `POST /track/event` **接口说明**: 前端主动上报埋点数据 **请求参数**: ```json { "eventType": "VIEW", "eventCategory": "TRAFFIC", "storeId": 1001, "targetId": 2001, "targetType": "PRICE", "eventData": "{}", "amount": 100.00, "duration": 3000 } ``` **响应示例**: ```json { "code": 200, "success": true, "msg": "上报成功", "data": null } ``` #### 6.2 手动触发统计接口(测试用) **接口路径**: `POST /track/statistics/calculate` **接口说明**: 手动触发统计数据计算 **请求参数**: - `storeId`: 店铺ID (必填) - `statDate`: 统计日期 (格式: yyyy-MM-dd) - `statType`: 统计类型 (DAILY/WEEKLY/MONTHLY) **响应示例**: ```json { "code": 200, "success": true, "msg": "统计数据计算成功", "data": null } ``` ## 七、事件类型枚举 ```java 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", "申诉"); } ``` ## 八、统计数据说明 ### 8.1 数据统计规则 | 数据类型 | 统计规则 | 说明 | |---------|---------|------| | 大部分数据 | **累计统计** | 统计截止到统计日期的所有数据 | | 新增访客数 | **增量统计** | 统计周期内的新增访客(排除之前访问过的用户) | ### 8.2 统计时间范围计算 | 统计类型 | 开始时间 | 结束时间 | |---------|---------|---------| | 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 | ### 8.3 JSON格式说明 详见:[埋点统计数据JSON格式说明.md](./埋点统计数据JSON格式说明.md) ## 九、部署和运维 ### 9.1 配置项 - Redis List最大长度: 100000 - 批量消费大小: 100 - 消费间隔: 10秒 - 统计数据保留期: 2年 ### 9.2 监控指标 - Redis List长度 - 消费延迟 - 消费失败率 - 统计查询响应时间 ### 9.3 Maven编译配置 确保pom.xml中配置了`-parameters`参数,以保留方法参数名称(SpEL表达式需要): ```xml org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 true ``` ## 十、注意事项 1. **埋点数据量可能很大**,需要定期清理历史数据 2. **Redis List需要设置最大长度**,防止内存溢出 3. **消费服务需要异常处理和重试机制** 4. **统计数据建议使用定时任务预计算**,提升查询性能 5. **AI推荐接口需要缓存**,避免频繁调用AI服务 6. **WebSocket埋点通过握手阶段获取IP和User-Agent**,需要配置自定义Configurator 7. **SpEL表达式无法直接获取storeId时**,切面会通过业务逻辑兜底查询 --- **文档版本**:v2.0 **最后更新**:2026-01-24