fix: rm skd file
This commit is contained in:
@@ -1,284 +0,0 @@
|
|||||||
# 数据埋点 API 调用示例
|
|
||||||
|
|
||||||
## 基础信息
|
|
||||||
|
|
||||||
- **接口路径**: `/doc_ai/v1/analytics/track`
|
|
||||||
- **请求方法**: `POST`
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **认证**: 可选(Bearer Token)
|
|
||||||
|
|
||||||
## 1. 基础埋点事件(最小参数)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "button_click"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. 完整埋点事件(包含所有字段)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "formula_recognition_start",
|
|
||||||
"properties": {
|
|
||||||
"file_name": "math_formula.png",
|
|
||||||
"file_size": 102400,
|
|
||||||
"file_type": "image/png",
|
|
||||||
"upload_method": "drag_drop"
|
|
||||||
},
|
|
||||||
"device_info": {
|
|
||||||
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
|
|
||||||
"screen_width": 1920,
|
|
||||||
"screen_height": 1080,
|
|
||||||
"language": "zh-CN",
|
|
||||||
"timezone": "Asia/Shanghai",
|
|
||||||
"platform": "MacIntel"
|
|
||||||
},
|
|
||||||
"meta_data": {
|
|
||||||
"task_id": "task_123456",
|
|
||||||
"timestamp": 1706342400000
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. 页面浏览事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "page_view",
|
|
||||||
"properties": {
|
|
||||||
"page_url": "https://example.com/home",
|
|
||||||
"page_title": "首页",
|
|
||||||
"page_name": "home",
|
|
||||||
"referrer": "https://example.com/login"
|
|
||||||
},
|
|
||||||
"device_info": {
|
|
||||||
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
|
|
||||||
"screen_width": 1920,
|
|
||||||
"screen_height": 1080
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. 任务相关事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "task_create",
|
|
||||||
"properties": {
|
|
||||||
"task_type": "formula_recognition",
|
|
||||||
"file_name": "equation.png",
|
|
||||||
"file_size": 204800
|
|
||||||
},
|
|
||||||
"meta_data": {
|
|
||||||
"task_id": "task_789012"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. 任务完成事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "task_complete",
|
|
||||||
"properties": {
|
|
||||||
"duration_seconds": 5.2,
|
|
||||||
"success": true,
|
|
||||||
"result_type": "latex"
|
|
||||||
},
|
|
||||||
"meta_data": {
|
|
||||||
"task_id": "task_789012"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. 表单提交事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "form_submit",
|
|
||||||
"properties": {
|
|
||||||
"form_name": "user_registration",
|
|
||||||
"form_fields": ["email", "password", "phone"],
|
|
||||||
"success": true,
|
|
||||||
"validation_errors": 0
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7. 文件上传事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "file_upload",
|
|
||||||
"properties": {
|
|
||||||
"file_name": "document.pdf",
|
|
||||||
"file_size": 5242880,
|
|
||||||
"file_type": "application/pdf",
|
|
||||||
"upload_source": "drag_drop",
|
|
||||||
"upload_duration_ms": 1200
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 8. 错误追踪事件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "error_occurred",
|
|
||||||
"properties": {
|
|
||||||
"error_type": "network_error",
|
|
||||||
"error_message": "Failed to fetch data",
|
|
||||||
"error_code": "NET_001",
|
|
||||||
"page_url": "https://example.com/tasks",
|
|
||||||
"user_action": "click_submit_button"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 9. 使用环境变量(推荐)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 设置环境变量
|
|
||||||
export API_BASE_URL="http://localhost:8080"
|
|
||||||
export JWT_TOKEN="YOUR_JWT_TOKEN"
|
|
||||||
export USER_ID=12345
|
|
||||||
|
|
||||||
# 调用接口
|
|
||||||
curl -X POST ${API_BASE_URL}/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer ${JWT_TOKEN}" \
|
|
||||||
-d "{
|
|
||||||
\"user_id\": ${USER_ID},
|
|
||||||
\"event_name\": \"button_click\",
|
|
||||||
\"properties\": {
|
|
||||||
\"button_name\": \"submit\",
|
|
||||||
\"button_position\": \"bottom\"
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 10. 使用 JSON 文件
|
|
||||||
|
|
||||||
创建 `event.json` 文件:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "custom_event",
|
|
||||||
"properties": {
|
|
||||||
"action": "click",
|
|
||||||
"element": "button",
|
|
||||||
"value": "submit"
|
|
||||||
},
|
|
||||||
"device_info": {
|
|
||||||
"user_agent": "Mozilla/5.0",
|
|
||||||
"screen_width": 1920,
|
|
||||||
"screen_height": 1080
|
|
||||||
},
|
|
||||||
"meta_data": {
|
|
||||||
"task_id": "task_123"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
然后执行:
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d @event.json
|
|
||||||
```
|
|
||||||
|
|
||||||
## 11. 批量埋点接口
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track/batch \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
|
||||||
-d '{
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "page_view",
|
|
||||||
"properties": {
|
|
||||||
"page_name": "home"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"user_id": 12345,
|
|
||||||
"event_name": "button_click",
|
|
||||||
"properties": {
|
|
||||||
"button_name": "start"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 响应示例
|
|
||||||
|
|
||||||
### 成功响应
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 200,
|
|
||||||
"message": "success",
|
|
||||||
"data": null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 错误响应
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 400,
|
|
||||||
"message": "invalid request",
|
|
||||||
"data": null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **user_id** 和 **event_name** 是必填字段
|
|
||||||
2. **properties**、**device_info**、**meta_data** 都是可选字段,类型为 JSON 对象
|
|
||||||
3. 如果提供了 Authorization header,token 中的 user_id 会被设置到上下文中,但请求体中的 user_id 仍然需要提供
|
|
||||||
4. 建议在生产环境中始终使用 HTTPS
|
|
||||||
5. 批量接口最多支持 100 个事件
|
|
||||||
|
|
||||||
## 测试命令(本地开发)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 最简单的测试
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"user_id": 1, "event_name": "test_event"}'
|
|
||||||
|
|
||||||
# 查看响应详情
|
|
||||||
curl -X POST http://localhost:8080/doc_ai/v1/analytics/track \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"user_id": 1, "event_name": "test_event"}' \
|
|
||||||
-v
|
|
||||||
```
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
// Analytics SDK for Frontend
|
|
||||||
// 前端数据埋点 SDK
|
|
||||||
|
|
||||||
interface EventProperties {
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DeviceInfo {
|
|
||||||
user_agent?: string;
|
|
||||||
screen_width?: number;
|
|
||||||
screen_height?: number;
|
|
||||||
language?: string;
|
|
||||||
timezone?: string;
|
|
||||||
platform?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MetaData {
|
|
||||||
task_id?: string | number;
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TrackEventParams {
|
|
||||||
event_name: string;
|
|
||||||
properties?: EventProperties;
|
|
||||||
device_info?: DeviceInfo;
|
|
||||||
meta_data?: MetaData;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AnalyticsConfig {
|
|
||||||
apiUrl: string;
|
|
||||||
token?: string;
|
|
||||||
userId?: number | string;
|
|
||||||
enableAutoTrack?: boolean;
|
|
||||||
debug?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Analytics {
|
|
||||||
private config: AnalyticsConfig;
|
|
||||||
private userId: number | string | null = null;
|
|
||||||
private eventQueue: TrackEventParams[] = [];
|
|
||||||
private isSending: boolean = false;
|
|
||||||
|
|
||||||
constructor(config: AnalyticsConfig) {
|
|
||||||
this.config = {
|
|
||||||
enableAutoTrack: true,
|
|
||||||
debug: false,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.config.userId) {
|
|
||||||
this.userId = this.config.userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动收集设备信息
|
|
||||||
if (this.config.enableAutoTrack) {
|
|
||||||
this.initAutoTrack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置用户ID
|
|
||||||
*/
|
|
||||||
setUserId(userId: number | string) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取设备信息
|
|
||||||
*/
|
|
||||||
private getDeviceInfo(): DeviceInfo {
|
|
||||||
return {
|
|
||||||
user_agent: navigator.userAgent,
|
|
||||||
screen_width: window.screen.width,
|
|
||||||
screen_height: window.screen.height,
|
|
||||||
language: navigator.language,
|
|
||||||
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
||||||
platform: navigator.platform,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记录单个事件
|
|
||||||
*/
|
|
||||||
async track(params: TrackEventParams): Promise<void> {
|
|
||||||
if (!this.userId) {
|
|
||||||
console.warn('Analytics: userId not set, event will not be tracked');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventData = {
|
|
||||||
user_id: this.userId,
|
|
||||||
event_name: params.event_name,
|
|
||||||
properties: params.properties || {},
|
|
||||||
device_info: {
|
|
||||||
...this.getDeviceInfo(),
|
|
||||||
...params.device_info,
|
|
||||||
},
|
|
||||||
meta_data: {
|
|
||||||
timestamp: Date.now(),
|
|
||||||
...params.meta_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.log('Analytics Track:', eventData);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.config.apiUrl}/track`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(this.config.token && { Authorization: `Bearer ${this.config.token}` }),
|
|
||||||
},
|
|
||||||
body: JSON.stringify(eventData),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to track event: ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.log('Analytics: Event tracked successfully');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Analytics: Failed to track event', error);
|
|
||||||
// 失败时加入队列,稍后重试
|
|
||||||
this.eventQueue.push(params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量记录事件
|
|
||||||
*/
|
|
||||||
async trackBatch(events: TrackEventParams[]): Promise<void> {
|
|
||||||
if (!this.userId) {
|
|
||||||
console.warn('Analytics: userId not set, events will not be tracked');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const batchData = {
|
|
||||||
events: events.map((params) => ({
|
|
||||||
user_id: this.userId,
|
|
||||||
event_name: params.event_name,
|
|
||||||
properties: params.properties || {},
|
|
||||||
device_info: {
|
|
||||||
...this.getDeviceInfo(),
|
|
||||||
...params.device_info,
|
|
||||||
},
|
|
||||||
meta_data: {
|
|
||||||
timestamp: Date.now(),
|
|
||||||
...params.meta_data,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.log('Analytics Track Batch:', batchData);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.config.apiUrl}/track/batch`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(this.config.token && { Authorization: `Bearer ${this.config.token}` }),
|
|
||||||
},
|
|
||||||
body: JSON.stringify(batchData),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to track batch events: ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.config.debug) {
|
|
||||||
console.log('Analytics: Batch events tracked successfully');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Analytics: Failed to track batch events', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面浏览事件
|
|
||||||
*/
|
|
||||||
trackPageView(pageName?: string) {
|
|
||||||
this.track({
|
|
||||||
event_name: 'page_view',
|
|
||||||
properties: {
|
|
||||||
page_url: window.location.href,
|
|
||||||
page_title: document.title,
|
|
||||||
page_name: pageName || document.title,
|
|
||||||
referrer: document.referrer,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击事件
|
|
||||||
*/
|
|
||||||
trackClick(elementName: string, properties?: EventProperties) {
|
|
||||||
this.track({
|
|
||||||
event_name: 'click',
|
|
||||||
properties: {
|
|
||||||
element_name: elementName,
|
|
||||||
page_url: window.location.href,
|
|
||||||
...properties,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单提交事件
|
|
||||||
*/
|
|
||||||
trackFormSubmit(formName: string, properties?: EventProperties) {
|
|
||||||
this.track({
|
|
||||||
event_name: 'form_submit',
|
|
||||||
properties: {
|
|
||||||
form_name: formName,
|
|
||||||
page_url: window.location.href,
|
|
||||||
...properties,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务相关事件
|
|
||||||
*/
|
|
||||||
trackTask(taskId: string | number, action: string, properties?: EventProperties) {
|
|
||||||
this.track({
|
|
||||||
event_name: `task_${action}`,
|
|
||||||
properties: {
|
|
||||||
action,
|
|
||||||
...properties,
|
|
||||||
},
|
|
||||||
meta_data: {
|
|
||||||
task_id: taskId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化自动埋点
|
|
||||||
*/
|
|
||||||
private initAutoTrack() {
|
|
||||||
// 页面加载完成时记录
|
|
||||||
if (document.readyState === 'complete') {
|
|
||||||
this.trackPageView();
|
|
||||||
} else {
|
|
||||||
window.addEventListener('load', () => this.trackPageView());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面离开前发送队列中的事件
|
|
||||||
window.addEventListener('beforeunload', () => {
|
|
||||||
if (this.eventQueue.length > 0) {
|
|
||||||
this.flushQueue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 页面可见性变化
|
|
||||||
document.addEventListener('visibilitychange', () => {
|
|
||||||
if (document.hidden && this.eventQueue.length > 0) {
|
|
||||||
this.flushQueue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新队列中的事件
|
|
||||||
*/
|
|
||||||
private flushQueue() {
|
|
||||||
if (this.isSending || this.eventQueue.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isSending = true;
|
|
||||||
const eventsToSend = [...this.eventQueue];
|
|
||||||
this.eventQueue = [];
|
|
||||||
|
|
||||||
this.trackBatch(eventsToSend).finally(() => {
|
|
||||||
this.isSending = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手动刷新队列
|
|
||||||
*/
|
|
||||||
flush() {
|
|
||||||
this.flushQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出单例实例
|
|
||||||
let analyticsInstance: Analytics | null = null;
|
|
||||||
|
|
||||||
export function initAnalytics(config: AnalyticsConfig): Analytics {
|
|
||||||
analyticsInstance = new Analytics(config);
|
|
||||||
return analyticsInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAnalytics(): Analytics {
|
|
||||||
if (!analyticsInstance) {
|
|
||||||
throw new Error('Analytics not initialized. Call initAnalytics first.');
|
|
||||||
}
|
|
||||||
return analyticsInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Analytics;
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
// Analytics SDK 使用示例
|
|
||||||
|
|
||||||
import { initAnalytics, getAnalytics } from './analytics';
|
|
||||||
|
|
||||||
// 1. 初始化 SDK
|
|
||||||
const analytics = initAnalytics({
|
|
||||||
apiUrl: 'https://your-api-domain.com/doc_ai/v1/analytics',
|
|
||||||
token: 'your-auth-token', // 从登录后获取
|
|
||||||
userId: 12345, // 用户ID
|
|
||||||
enableAutoTrack: true, // 启用自动埋点(页面浏览等)
|
|
||||||
debug: true, // 开发环境下启用调试
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. 设置用户ID(登录后)
|
|
||||||
analytics.setUserId(12345);
|
|
||||||
|
|
||||||
// 3. 记录页面浏览
|
|
||||||
analytics.trackPageView('首页');
|
|
||||||
|
|
||||||
// 4. 记录点击事件
|
|
||||||
const handleButtonClick = () => {
|
|
||||||
analytics.trackClick('提交按钮', {
|
|
||||||
button_text: '提交',
|
|
||||||
button_position: 'bottom',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 5. 记录表单提交
|
|
||||||
const handleFormSubmit = (formData: any) => {
|
|
||||||
analytics.trackFormSubmit('用户注册表单', {
|
|
||||||
form_fields: Object.keys(formData),
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 6. 记录任务相关事件
|
|
||||||
const handleTaskCreate = (taskId: string) => {
|
|
||||||
analytics.trackTask(taskId, 'create', {
|
|
||||||
task_type: 'formula_recognition',
|
|
||||||
file_type: 'image/png',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTaskComplete = (taskId: string) => {
|
|
||||||
analytics.trackTask(taskId, 'complete', {
|
|
||||||
duration_seconds: 5.2,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 7. 记录自定义事件
|
|
||||||
const handleFileUpload = (file: File) => {
|
|
||||||
analytics.track({
|
|
||||||
event_name: 'file_upload',
|
|
||||||
properties: {
|
|
||||||
file_name: file.name,
|
|
||||||
file_size: file.size,
|
|
||||||
file_type: file.type,
|
|
||||||
},
|
|
||||||
meta_data: {
|
|
||||||
upload_source: 'drag_drop',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 8. 批量记录事件
|
|
||||||
const handleBatchActions = () => {
|
|
||||||
analytics.trackBatch([
|
|
||||||
{
|
|
||||||
event_name: 'button_click',
|
|
||||||
properties: { button_name: 'save' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
event_name: 'data_export',
|
|
||||||
properties: { format: 'pdf' },
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 9. React 组件中使用
|
|
||||||
import React, { useEffect } from 'react';
|
|
||||||
|
|
||||||
function HomePage() {
|
|
||||||
useEffect(() => {
|
|
||||||
// 页面加载时记录
|
|
||||||
getAnalytics().trackPageView('首页');
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleClick = () => {
|
|
||||||
getAnalytics().trackClick('首页-开始按钮');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>首页</h1>
|
|
||||||
<button onClick={handleClick}>开始</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10. Vue 组件中使用
|
|
||||||
export default {
|
|
||||||
name: 'HomePage',
|
|
||||||
mounted() {
|
|
||||||
getAnalytics().trackPageView('首页');
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleClick() {
|
|
||||||
getAnalytics().trackClick('首页-开始按钮');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// 11. 记录用户行为流程
|
|
||||||
class FormulaRecognitionFlow {
|
|
||||||
private analytics = getAnalytics();
|
|
||||||
private taskId: string | null = null;
|
|
||||||
|
|
||||||
// 开始识别流程
|
|
||||||
startRecognition(file: File) {
|
|
||||||
this.analytics.track({
|
|
||||||
event_name: 'formula_recognition_start',
|
|
||||||
properties: {
|
|
||||||
file_name: file.name,
|
|
||||||
file_size: file.size,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上传成功
|
|
||||||
uploadSuccess(taskId: string) {
|
|
||||||
this.taskId = taskId;
|
|
||||||
this.analytics.trackTask(taskId, 'upload_success', {
|
|
||||||
step: 'upload',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 识别进行中
|
|
||||||
recognitionProcessing() {
|
|
||||||
if (this.taskId) {
|
|
||||||
this.analytics.trackTask(this.taskId, 'processing', {
|
|
||||||
step: 'recognition',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 识别完成
|
|
||||||
recognitionComplete(result: any) {
|
|
||||||
if (this.taskId) {
|
|
||||||
this.analytics.trackTask(this.taskId, 'complete', {
|
|
||||||
step: 'complete',
|
|
||||||
has_result: !!result,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 识别失败
|
|
||||||
recognitionFailed(error: string) {
|
|
||||||
if (this.taskId) {
|
|
||||||
this.analytics.trackTask(this.taskId, 'failed', {
|
|
||||||
step: 'error',
|
|
||||||
error_message: error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看结果
|
|
||||||
viewResult() {
|
|
||||||
if (this.taskId) {
|
|
||||||
this.analytics.trackTask(this.taskId, 'view_result', {
|
|
||||||
step: 'view',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出结果
|
|
||||||
exportResult(format: string) {
|
|
||||||
if (this.taskId) {
|
|
||||||
this.analytics.trackTask(this.taskId, 'export', {
|
|
||||||
step: 'export',
|
|
||||||
export_format: format,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 12. 错误追踪
|
|
||||||
window.addEventListener('error', (event) => {
|
|
||||||
getAnalytics().track({
|
|
||||||
event_name: 'javascript_error',
|
|
||||||
properties: {
|
|
||||||
error_message: event.message,
|
|
||||||
error_filename: event.filename,
|
|
||||||
error_line: event.lineno,
|
|
||||||
error_column: event.colno,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 13. 性能追踪
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
const perfData = performance.timing;
|
|
||||||
const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
|
|
||||||
|
|
||||||
getAnalytics().track({
|
|
||||||
event_name: 'page_performance',
|
|
||||||
properties: {
|
|
||||||
page_load_time: pageLoadTime,
|
|
||||||
dns_time: perfData.domainLookupEnd - perfData.domainLookupStart,
|
|
||||||
tcp_time: perfData.connectEnd - perfData.connectStart,
|
|
||||||
request_time: perfData.responseEnd - perfData.requestStart,
|
|
||||||
dom_parse_time: perfData.domComplete - perfData.domLoading,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
export {};
|
|
||||||
Reference in New Issue
Block a user