请前端统一使用
/analytics/front接口,不要再调用旧接口POST /track/event。
| 接口 | 说明 |
|---|---|
POST /analytics/front/report |
主入口,传 scene 即可 |
POST /analytics/front/batch |
批量上报(最多50条) |
POST /analytics/front/heartbeat |
在线心跳(统计在线时长) |
POST /analytics/front/user/register |
用户注册埋点 |
POST /analytics/front/user/login |
用户登录埋点 |
POST /analytics/front/user/logout |
用户登出埋点 |
POST /analytics/front/ai-chat/end |
AI对话结束埋点 |
POST /analytics/front/content/publish |
内容发布埋点 |
POST /analytics/front/content/interact |
内容互动埋点(评论/点赞/收藏) |
POST /analytics/front/merchant/view |
商家浏览埋点 |
POST /analytics/front/ai-request |
AI 请求耗时上报 |
GET /analytics/front/scenes |
获取全部 scene 列表 |
明细同步(业务侧主动推送完整字段):
| 接口 | 说明 |
|---|---|
POST /analytics/detail/user |
用户明细 |
POST /analytics/detail/merchant |
商户明细 |
POST /analytics/detail/content |
内容明细 |
POST /analytics/detail/ai-chat |
AI 对话明细 |
将 alien-store/doc/analytics-front-sdk.js 复制到前端项目 utils/analytics.js。
import Analytics from '@/utils/analytics.js';
Analytics.init({
baseUrl: 'https://your-api.com',
getToken: () => uni.getStorageSync('token'),
channel: 'app_store',
});
Analytics.onLaunch();
Analytics.startHeartbeat(60000, { userId: () => uni.getStorageSync('userId') });
// 用户注册(建议补充性别/年龄段,用于用户报表分布)
Analytics.userRegister({
userId: 10001,
userPhone: '13800138000',
registerTime: '2026-06-15 10:00:00',
channel: 'app_store',
city: '北京',
gender: 1, // 0未知 1男 2女
age: 28,
ageGroup: '25-29', // 18-24|25-29|30-34|35-39|40-49|50+
});
// 登录成功
Analytics.userLogin({
userId: 10001,
city: '北京',
deviceName: 'iPhone 15',
});
// 登出
Analytics.userLogout({
userId: 10001,
city: '北京',
deviceName: 'iPhone 15',
onlineDurationMin: 30,
});
Analytics.aiChatEnd({
chatId: 'chat-uuid-001',
userId: 10001,
startTime: '2026-06-15 14:00:00',
messageCount: 12,
aiResponseDurationMs: 8500,
});
Analytics.contentPublish({
contentId: 90001,
contentType: 1, // 1动态 2打卡 3二手商品
contentTitle: '大连最好吃的5家日料店推荐',
businessCategory: 1, // 1美食 2休闲娱乐 3生活服务 4旅游 5酒店 6购物 7其他
authorType: 1, // 1用户 2商家
authorId: 10001,
publishTime: '2026-06-15 16:00:00',
});
// 点赞 +1(建议传 eventSubtype 便于拆分点赞/评论/分享)
Analytics.contentInteract({
contentId: 90001,
contentType: 1,
increment: 1,
userId: 10001,
eventSubtype: 'like', // like | comment | share
});
// 取消点赞 -1
Analytics.contentInteract({
contentId: 90001,
contentType: 1,
increment: -1,
userId: 10001,
});
// 兼容旧写法(默认 increment=1)
Analytics.onContentInteract(90001, 1, { userId: 10001 });
// 进入商家页:PV+1,当日首次访问 UV+1
Analytics.merchantView({
merchantId: 20001,
shopType: 1, // 1美食 2休闲娱乐 3生活服务
visitPv: 1,
visitUv: 1,
userId: 10001,
});
// 商户转化漏斗(列表曝光 → 点击 → 详情 → 电话/导航)
Analytics.report('MERCHANT_EXPOSE', { merchantId: 20001, shopType: 1 });
Analytics.report('MERCHANT_CLICK', { merchantId: 20001, shopType: 1 });
Analytics.report('MERCHANT_DETAIL', { merchantId: 20001, shopType: 1 });
Analytics.report('MERCHANT_CONTACT', { merchantId: 20001, shopType: 1 });
// 注册转化漏斗
Analytics.report('REGISTER_PAGE', { channel: 'app_store' });
Analytics.report('REGISTER_PHONE', { userPhone: '13800138000' });
Analytics.report('REGISTER_OTP', { userPhone: '13800138000' });
Analytics.report('REGISTER_PASSWORD', { userPhone: '13800138000' });
// 兼容旧写法(需传 shopType、visitPv、visitUv)
Analytics.onMerchantView(20001, {
shopType: 1,
visitPv: 1,
visitUv: 1,
userId: 10001,
});
// 访问商户页
Analytics.onMerchantView(merchantId, {
shopType: 1,
visitPv: 1,
visitUv: 1,
});
// 内容互动(contentType: 1动态 2打卡 3二手商品)
Analytics.onContentInteract(contentId, 1);
// 支付成功(建议传 merchantId、businessCategory 支撑商家 GMV 分类)
Analytics.report('PAY_SUCCESS', {
amount: 99.00,
targetId: orderId,
merchantId: 20001,
businessCategory: 1,
});
// AI 请求耗时
Analytics.aiRequest({
apiName: 'chat.completion',
apiUrl: '/api/ai/chat',
responseDurationMs: 1200,
isTimeout: 0,
});
analytics_event 表每个业务值对应独立列,不使用 JSON 扩展字段:
| 字段 | 说明 |
|---|---|
| userId / merchantId / targetId | 用户、商户、目标对象 |
| contentType | 1动态 2打卡 3二手商品 |
| eventSubtype | 事件子类型(见下方枚举) |
| businessCategory | 经营品类(见下方枚举,内容发布/支付时建议传) |
| amount / durationMs | 金额、时长 |
| deviceType / channel / city | 设备、渠道、城市 |
| scene | 含义 | 主要参数 |
|---|---|---|
APP_LAUNCH |
App 启动 | channel, city |
APP_REGISTER |
用户注册 | - |
USER_HEARTBEAT |
在线心跳 | durationMs |
MERCHANT_EXPOSE |
商户曝光 | merchantId, shopType |
MERCHANT_CLICK |
商户点击 | merchantId, shopType |
MERCHANT_DETAIL |
商户详情 | merchantId, shopType |
MERCHANT_CONTACT |
电话/导航 | merchantId, shopType |
MERCHANT_VIEW |
访问商户 | merchantId |
MERCHANT_VERIFY |
商户核销 | merchantId, amount |
REGISTER_PAGE |
进入注册页 | channel |
REGISTER_PHONE |
提交手机号 | userPhone |
REGISTER_OTP |
验证码通过 | userPhone |
REGISTER_PASSWORD |
设置密码 | userPhone |
CONTENT_PUBLISH |
发布内容 | targetId, contentType |
CONTENT_INTERACT |
内容互动 | targetId, contentType, eventSubtype |
PAY_SUCCESS |
支付成功 | targetId, amount, merchantId, businessCategory |
AI_CHAT_START |
AI 对话开始 | - |
REPORT_SUBMIT |
提交举报 | targetId |
AUDIT_SUBMIT |
提交审核 | targetId, contentType |
AUDIT_REJECT |
审核驳回 | targetId, contentType, eventSubtype=reject |
完整列表调用:GET /analytics/front/scenes
| 值 | 含义 | 适用 scene |
|---|---|---|
like |
点赞 | CONTENT_INTERACT |
comment |
评论 | CONTENT_INTERACT |
share |
分享 | CONTENT_INTERACT |
ai_pass |
AI审核通过 | AUDIT_SUBMIT |
manual_pass |
人工审核通过 | AUDIT_SUBMIT |
reject |
审核驳回 | AUDIT_REJECT |
| 值 | 含义 |
|---|---|
| 1 | 美食 |
| 2 | 休闲娱乐 |
| 3 | 生活服务 |
| 4 | 旅游 |
| 5 | 酒店 |
| 6 | 购物 |
| 7 | 其他 |
POST /analytics/front/report
Authorization: Bearer {token}
Content-Type: application/json
{
"scene": "MERCHANT_VIEW",
"eventId": "a1b2c3d4e5f6",
"merchantId": 1001,
"city": "北京",
"channel": "ios"
}
userId可不传,服务端从 JWT 自动解析。
POST /analytics/front/heartbeat
{
"userId": 10001,
"durationMs": 60000,
"deviceType": "iOS 17",
"city": "大连"
}
userId必填(用于写入当日用户明细、支撑「当前在线用户」看板)。除事件表外,会同步更新analytics_user_stat_today的last_active_time与online_duration_min。
POST /analytics/front/user/register
{
"userId": 10001,
"userPhone": "13800138000",
"registerTime": "2026-06-15 10:00:00",
"channel": "app_store",
"city": "北京"
}
注册成功后会写入当日用户明细,并标记
is_new_user = 1。
POST /analytics/front/user/login
{
"userId": 10001,
"lastActiveTime": "2026-06-15 14:30:00",
"city": "北京",
"deviceName": "iPhone 15"
}
POST /analytics/front/user/logout
{
"userId": 10001,
"lastActiveTime": "2026-06-15 15:00:00",
"city": "北京",
"deviceName": "iPhone 15",
"onlineDurationMin": 30
}
POST /analytics/front/ai-chat/end
{
"chatId": "chat-uuid-001",
"userId": 10001,
"startTime": "2026-06-15 14:00:00",
"messageCount": 12,
"aiResponseDurationMs": 8500
}
POST /analytics/front/content/publish
{
"contentId": 90001,
"contentType": 1,
"contentTitle": "大连最好吃的5家日料店推荐",
"businessCategory": 1,
"authorType": 1,
"authorId": 10001,
"publishTime": "2026-06-15 16:00:00"
}
contentTitle、businessCategory用于内容发布明细看板,建议发布时必传。
POST /analytics/front/content/interact
{
"contentId": 90001,
"contentType": 1,
"increment": 1,
"userId": 10001
}
increment由前端决定增减幅度:评论/点赞/收藏传正数,取消操作传负数。会实时累加到analytics_content_stat_today.interaction_count。
POST /analytics/front/merchant/view
{
"merchantId": 20001,
"shopType": 1,
"visitUv": 1,
"visitPv": 1,
"userId": 10001
}
visitUv、visitPv为当日增量:通常 PV 传 1;UV 在当日首次访问该商家时传 1,否则传 0。
POST /analytics/detail/merchant
{
"merchantId": 20001,
"shopType": 1,
"visitUv": 100,
"visitPv": 500,
"settleStatus": 1
}
明细同步接口中
visitUv/visitPv为覆盖写入;浏览埋点/merchant/view为累加写入,请勿混用语义。用户名称、商家名称、作者名称等展示字段不入库、不上报,查询明细时由服务端按 ID 回填。
POST /analytics/front/ai-request
{
"apiName": "chat.completion",
"apiUrl": "/api/ai/chat",
"responseDurationMs": 1200,
"isTimeout": 0
}
埋点实时写入 今日明细表,每天零点由定时任务归档到历史表(保留 30 天):
| 维度 | 今日表 | 历史表 | 唯一键(今日) |
|---|---|---|---|
| 用户 | analytics_user_stat_today |
analytics_user_stat_history |
user_id(每用户每日一行) |
| 商户 | analytics_merchant_stat_today |
analytics_merchant_stat_history |
merchant_id(每商家每日一行) |
| 内容 | analytics_content_stat_today |
analytics_content_stat_history |
content_type + content_id |
is_new_user = 1,用于「新增用户明细」查询。建表脚本(新环境执行一次):
alien-entity/src/main/resources/db/migration/analytics_schema.sql
旧环境升级见同目录 analytics_tables_dashboard_upgrade.sql。
eventId(前端 UUID)eventId 重复提交会被服务端忽略,不会重复计数埋点写明细与事件,看板 KPI 由 alien-job 定时任务或手动接口汇总到 analytics_daily_summary。
| Handler | Cron 建议 | 说明 |
|---|---|---|
analyticsArchiveDaily |
0 0 0 * * ? |
零点将昨日今日表明细归档到历史表 |
analyticsCalculateTodayHourly |
5 5 * * * ? |
每小时第5分钟汇总当日(避开零点归档) |
analyticsCalculateYesterdayDaily |
0 0 2 * * ? |
凌晨 2 点汇总前日(在归档之后) |
analyticsCalculateRetention |
0 0 3 * * ? |
凌晨 3 点计算留存 |
POST /analytics/stat/calculate
{ "statDate": "2026-06-15", "scope": "ALL" }
POST /analytics/stat/archive
周期参数(四个报表模块通用):period=TODAY|YESTERDAY|LAST_7D|LAST_30D
| 模块 | 汇总接口 | 说明 |
|---|---|---|
| 数据看板 | GET /analytics/dashboard/charts?period= |
含顶部 KPI + 6 张图表 |
| 数据看板 | GET /analytics/dashboard/summary?period= |
仅顶部 KPI |
| 用户报表 | GET /analytics/user-report/charts?period=&detailPage=1&detailSize=10 |
含新注册用户明细分页 |
| 内容报表 | GET /analytics/content-report/charts?period=&detailPage=1&detailSize=10 |
含审核通过列表分页 |
| 商家报表 | GET /analytics/merchant-report/charts?period= |
GMV/分类/客单价趋势等 |
| 接口 | 说明 |
|---|---|
GET /analytics/stat/daily?statDate= |
平台日统计 KPI |
GET /analytics/stat/user/page?statDate= |
DAU 用户明细 |
GET /analytics/stat/user/new/page?statDate= |
新增用户明细 |
GET /analytics/stat/user/online/page?onlineWithinMin=5 |
当前在线用户(仅今日) |
GET /analytics/stat/merchant/page?statDate= |
商家访问 UV 明细 |
GET /analytics/stat/content/page?statDate=&contentType= |
内容发布明细 |
GET /analytics/stat/conversion/page?startDate=&endDate= |
转化率日明细 |
查询历史日期时读历史表;
statDate为空或当天时读今日表。
alien-store/src/main/java/shop/alien/store/
├── controller/analytics/
│ ├── AnalyticsFrontController # 前端上报 /analytics/front/*
│ ├── AnalyticsDetailController # 明细上报 /analytics/detail/*
│ ├── AnalyticsStatController # 统计查询 /analytics/stat/*
│ └── AnalyticsJobController # 定时任务回调 /analytics/job/*
├── service/analytics/
└── util/analytics/
alien-job/src/main/java/shop/alien/job/store/
└── AnalyticsStatisticsJob # XXL-JOB 调度入口