@kbapp/data-analysis 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD ADDED
@@ -0,0 +1,454 @@
1
+ # 开吧App埋点平台
2
+
3
+ > ⚠️ 重要提示:本 SDK 基于 TypeScript 开发,所有 API 参数均带有明确的必填 / 选填类型标注。使用时请务必开启 TS 类型检查或在 IDE 中查看参数提示,必填项缺失会直接提示错误,选填项可按需传入,请勿忽略类型提示以避免使用异常。
4
+
5
+ ## 功能特点
6
+
7
+ - 异步加载核心上报SDK,避免包体积过大
8
+ - 支持全局公共属性设置
9
+ - 提供普通事件和持续事件(开始/结束)上报
10
+ - 内置标准事件模型(DocActionEvent、DocVisitEvent)
11
+ - 完全TypeScript支持,提供完整的类型定义
12
+
13
+ ## 下载
14
+
15
+ npm:
16
+
17
+ ```bash
18
+ npm install @kbapp/data-analysis
19
+ ```
20
+
21
+ ### 或通过 script 标签引入
22
+
23
+ 使用 unpkg CDN:
24
+
25
+ ```html
26
+ <script src="https://unpkg.com/@kbapp/data-analysis@latest/dist/index.umd.js"></script>
27
+ ```
28
+
29
+ 使用 jsdelivr CDN:
30
+
31
+ ```html
32
+ <script src="https://cdn.jsdelivr.net/npm/@kbapp/data-analysis@latest/dist/index.umd.js"></script>
33
+ ```
34
+
35
+ > 通过 script 标签引入后,SDK 将作为全局变量 `kbDataAnalysis` 挂载在 window 对象上
36
+
37
+ ## 基本使用
38
+
39
+ ### 1. 初始化埋点实例
40
+
41
+ 通过 npm 安装并使用 ES module 导入:
42
+
43
+ ```typescript
44
+ import { DataAnalysis } from '@kbapp/data-analysis';
45
+
46
+ // 创建埋点实例,初始化时可以配置埋点上报域名和应用ID
47
+ const kbTracker = new DataAnalysis({
48
+ sdkUrl: 'https://page.kaiba315.com.cn/js/gsido-h5-min-1.0.7.1_final.js',
49
+ appid: '由开吧分配',
50
+ debugger: false, // 开发环境可设为 true,开启埋点日志输出
51
+ });
52
+ ```
53
+
54
+ 通过 script 标签引入并使用全局变量:
55
+
56
+ ```html
57
+ <script src="https://unpkg.com/@kbapp/data-analysis@latest/dist/index.umd.js"></script>
58
+
59
+ <script>
60
+ // 通过全局变量kbDataAnalysis创建埋点实例
61
+ const kbTracker = new kbDataAnalysis.DataAnalysis({
62
+ sdkUrl: 'https://page.kaiba315.com.cn/js/gsido-h5-min-1.0.7.1_final.js',
63
+ appid: '由开吧分配',
64
+ debugger: false, // 开发环境可设为 true,开启埋点日志输出
65
+ });
66
+ </script>
67
+ ```
68
+
69
+ ### 2. 设置全局公共属性
70
+
71
+ ```typescript
72
+ // 全局公共属性将附加到所有上报事件中
73
+ kbTracker.setReportGlobalAttrs({
74
+ userId: '123456', // 用户唯一标识
75
+ platform: 'h5', // 平台类型(h5/ios/android)
76
+ appVersion: '1.0.0', // APP版本号
77
+ });
78
+
79
+ // 支持多次调用,属性将合并
80
+ kbTracker.setReportGlobalAttrs({
81
+ channel: 'official',
82
+ });
83
+ ```
84
+
85
+ ### 3. 上报普通事件
86
+
87
+ ```typescript
88
+ // 基本事件上报
89
+ kbTracker.report({
90
+ name: 'page_view', // 事件名称
91
+ params: {
92
+ pageId: 'home_page',
93
+ stayTime: 1000,
94
+ // 其他自定义参数...
95
+ },
96
+ });
97
+ ```
98
+
99
+ ### 4. 上报持续事件
100
+
101
+ ```typescript
102
+ // 开始持续事件
103
+ kbTracker.reportBeginEvent({
104
+ name: 'video_play',
105
+ params: {
106
+ videoId: 'v001',
107
+ startTime: Date.now(),
108
+ },
109
+ });
110
+
111
+ // 结束持续事件(需要与开始事件使用相同的事件名)
112
+ kbTracker.reportEndEvent({
113
+ name: 'video_play',
114
+ params: {
115
+ videoId: 'v001',
116
+ endTime: Date.now(),
117
+ duration: 60000,
118
+ },
119
+ });
120
+ ```
121
+
122
+ ### 5. 使用标准事件模型
123
+
124
+ #### 5.1 稿件浏览事件(DocVisitEvent)
125
+
126
+ ```typescript
127
+ import { DocVisitEvent } from '@kbapp/data-analysis';
128
+
129
+ kbTracker.report({
130
+ name: 'DocVisitEvent',
131
+ params: DocVisitEvent.createDocTrackEvent({
132
+ biz: '业务类型',
133
+ unit: '业务单元',
134
+ ref1: '对象标识1 可为空',
135
+ ref2: '对象标识2 可为空',
136
+ ref3: '对象标识3 可为空',
137
+ sid: '站点 ID 可为空',
138
+ title: '稿件标题',
139
+ channel: '所属单位 可为空',
140
+ depart: '所属部门 可为空',
141
+ suid: '分享人的用用户id 可为空'
142
+ }),
143
+ });
144
+ ```
145
+
146
+ #### 5.2 稿件动作事件(DocActionEvent)
147
+
148
+ ```typescript
149
+ import { DocActionEvent } from '@kbapp/data-analysis';
150
+
151
+ kbTracker.report({
152
+ name: 'DocActionEvent',
153
+ params: DocActionEvent.createDocTrackEvent({
154
+ act: '动作标识',
155
+ biz: '业务类型',
156
+ unit: '业务单元',
157
+ ref1: '对象标识1 可为空',
158
+ ref2: '对象标识2 可为空',
159
+ ref3: '对象标识3 可为空',
160
+ sid: '站点 ID 可为空',
161
+ title: '稿件标题',
162
+ channel: '所属单位 可为空',
163
+ depart: '所属部门 可为空',
164
+ suid: '分享人的用用户id 可为空'
165
+ }),
166
+ });
167
+ ```
168
+
169
+ ## API 参考
170
+
171
+ ### DataAnalysis 类
172
+
173
+ #### 构造函数
174
+
175
+ ```typescript
176
+ constructor(params: {
177
+ sdkUrl: string; // 个推SDK地址
178
+ appid: string; // 埋点应用ID
179
+ debugger?: boolean; // 是否开启调试模式
180
+ })
181
+ ```
182
+
183
+ #### 方法
184
+
185
+ ##### setReportGlobalAttrs
186
+ 设置全局公共属性,将附加到所有上报事件中
187
+
188
+ ```typescript
189
+ setReportGlobalAttrs(attrs: Record<string, any> = {}): void
190
+ ```
191
+
192
+ ##### report
193
+ 上报普通事件
194
+
195
+ ```typescript
196
+ report(params: {
197
+ name: string; // 事件名称
198
+ params?: Record<string, any>; // 事件参数
199
+ }): void
200
+ ```
201
+
202
+ ##### reportBeginEvent
203
+ 上报持续事件的开始
204
+
205
+ ```typescript
206
+ reportBeginEvent(params: {
207
+ name: string; // 事件名称
208
+ params?: Record<string, any>; // 事件参数
209
+ }): void
210
+ ```
211
+
212
+ ##### reportEndEvent
213
+ 上报持续事件的结束
214
+
215
+ ```typescript
216
+ reportEndEvent(params: {
217
+ name: string; // 事件名称(需与开始事件相同)
218
+ params?: Record<string, any>; // 事件参数
219
+ }): void
220
+ ```
221
+
222
+ ##### getGsido
223
+ 获取原始的 GsIdo 对象(慎用)
224
+
225
+ ```typescript
226
+ getGsido(): typeof GsIdo | undefined
227
+ ```
228
+
229
+ ### 标准事件模型
230
+
231
+ #### DocVisitEvent
232
+ 稿件浏览事件,用于记录用户访问稿件的行为
233
+
234
+ ```js
235
+ class DocVisitEvent {
236
+ /**
237
+ * 访问来源, {@link Doc#getDocId()} 上级页面的稿件标识. 可为空.
238
+ */
239
+ referer?: string
240
+
241
+ /**
242
+ * 业务类型. {@link KbModule}. 非空.
243
+ */
244
+ biz: string
245
+
246
+ /**
247
+ * 业务单元. 用以保持稿件定义的同构性: 同一个业务单元下的 ref 含义和层级结构总是一致的. 可为空.
248
+ */
249
+ unit?: string
250
+
251
+ /**
252
+ * 对象标识1. 非空.
253
+ */
254
+ ref1: string
255
+
256
+ /**
257
+ * 对象标识2. 可为空.
258
+ */
259
+ ref2?: string
260
+
261
+ /**
262
+ * 对象标识3. 可为空.
263
+ */
264
+ ref3?: string
265
+
266
+ /**
267
+ * 站点 ID. 可为空.
268
+ */
269
+ sid?: number
270
+
271
+ /**
272
+ * 稿件标题. 非空.
273
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
274
+ */
275
+ title: string
276
+
277
+ /**
278
+ * 所属单位. 可为空.
279
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
280
+ */
281
+ channel?: string
282
+
283
+ /**
284
+ * 所属部门. 部门是单位的下属组织. 可为空.
285
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
286
+ */
287
+ depart?: string
288
+
289
+ /** 分享人的用用户id, 分享出去的链接自动追加 suid=xxx */
290
+ suid?: string
291
+
292
+ /** 稿件标识, 拼接非空字段得到: biz-unit-ref1-ref2-ref3-siteId, 可通过 createDocTrackEvent 自动生成 */
293
+ docId!: string
294
+
295
+ constructor(params: Omit<DocVisitEvent, 'docId'>) {
296
+ this.biz = params.biz
297
+ this.unit = params.unit
298
+ this.ref1 = params.ref1
299
+ this.ref2 = params.ref2
300
+ this.ref3 = params.ref3
301
+ this.sid = params.sid
302
+ this.title = params.title
303
+ this.channel = params.channel
304
+ this.depart = params.depart
305
+ this.referer = params.referer
306
+ this.suid = params.suid
307
+
308
+ Object.defineProperty(this, 'docId', {
309
+ enumerable: true,
310
+ configurable: false,
311
+ get: () => {
312
+ return DocVisitEvent.generateDocId(this)
313
+ },
314
+ })
315
+ }
316
+
317
+ /**
318
+ *
319
+ * @description 生成稿件标识
320
+ */
321
+ static generateDocId(params: DocVisitEvent) {
322
+ return [params.biz, params.unit, params.ref1, params.ref2, params.ref3, params.sid].filter((value) => !!value).join('-')
323
+ }
324
+
325
+ /**
326
+ *
327
+ * @description 生成稿件数据(自动生成docId)
328
+ */
329
+ static createDocTrackEvent(params: Omit<DocVisitEvent, 'docId'>) {
330
+ return filterUndefinedProperties(new DocVisitEvent(params))
331
+ }
332
+ }
333
+ ```
334
+
335
+ #### DocActionEvent
336
+ 稿件动作事件,用于记录用户对稿件的操作行为
337
+
338
+
339
+ ```js
340
+ class DocActionEvent {
341
+ /**
342
+ * 动作标识. 以下为保留关键字, 语义相同的动作请复用如下定义:
343
+ * 点赞: like
344
+ * 分享: share
345
+ * 评论: reply
346
+ * 评论的评论: reply_r
347
+ * 评论的点赞: reply_l
348
+ * 投票: vote
349
+ * 签到: sign
350
+ * 购买: buy
351
+ * 打赏: reward
352
+ *
353
+ * 动作语义不符合如上定义时, 请自行定义动作标识.
354
+ */
355
+ act: string
356
+
357
+ /** 业务类型. {@link KbModule}. 非空. */
358
+ biz: string
359
+
360
+ /** 业务单元. 用以保持稿件定义的同构性: 同一个业务单元下的 ref 含义和层级结构总是一致的. 可为空. */
361
+ unit?: string
362
+
363
+ /** 对象标识1. 非空. */
364
+ ref1: string
365
+
366
+ /** 对象标识2. 可为空. */
367
+ ref2?: string
368
+
369
+ /** 对象标识3. 可为空. */
370
+ ref3?: string
371
+
372
+ /** 站点 ID. 可为空. */
373
+ sid?: number
374
+
375
+ /**
376
+ * 稿件标题. 非空.
377
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
378
+ */
379
+ title: string
380
+
381
+ /**
382
+ * 所属单位. 可为空.
383
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
384
+ */
385
+ channel?: string
386
+
387
+ /**
388
+ * 所属部门. 部门是单位的下属组织. 可为空.
389
+ * 此为冗余字段, 以便在分析平台查询. 考核统计场景下应使用维表.
390
+ */
391
+ depart?: string
392
+
393
+ /** 分享人的用用户id, 分享出去的链接自动追加 suid=xxx */
394
+ suid?: string
395
+
396
+ /** 稿件标识, 拼接非空字段得到: biz-unit-ref1-ref2-ref3-siteId */
397
+ docId!: string
398
+
399
+ constructor(params: Omit<DocActionEvent, 'docId'>) {
400
+ this.act = params.act
401
+ this.biz = params.biz
402
+ this.unit = params.unit
403
+ this.ref1 = params.ref1
404
+ this.ref2 = params.ref2
405
+ this.ref3 = params.ref3
406
+ this.sid = params.sid
407
+ this.title = params.title
408
+ this.channel = params.channel
409
+ this.depart = params.depart
410
+ this.suid = params.suid
411
+
412
+ Object.defineProperty(this, 'docId', {
413
+ enumerable: true,
414
+ configurable: false,
415
+ get: () => {
416
+ return DocActionEvent.generateDocId(this)
417
+ },
418
+ })
419
+ }
420
+
421
+ /**
422
+ *
423
+ * @description 生成稿件标识
424
+ */
425
+ static generateDocId(params: DocActionEvent) {
426
+ return [params.biz, params.unit, params.ref1, params.ref2, params.ref3, params.sid].filter((value) => !!value).join('-')
427
+ }
428
+
429
+ /**
430
+ *
431
+ * @description 生成稿件数据(自动生成docId)
432
+ */
433
+ static createDocTrackEvent(params: Omit<DocActionEvent, 'docId'>) {
434
+ return filterUndefinedProperties(new DocActionEvent(params))
435
+ }
436
+ }
437
+ ```
438
+
439
+ ## 最佳实践
440
+
441
+ 1. **全局唯一实例**:建议在应用入口处创建一个全局唯一的DataAnalysis实例
442
+ 4. **合理使用全局属性**:将通用信息(如用户ID、平台等)设置为全局属性
443
+ 5. **开发环境开启调试**:在开发环境设置`debugger: true`以查看埋点日志
444
+
445
+ ## 注意事项
446
+
447
+ 1. `sdkUrl`和`appid`是必需参数,需要正确配置
448
+ 2. DocActionEvent中的`act`字段有标准值,语义相同时应复用(如点赞使用'like')
449
+
450
+ ## 依赖
451
+
452
+ - lodash.clonedeep: 用于深度克隆对象,确保属性合并时不影响原始数据
453
+ - @kbapp/open-jssdk: 提供开吧App环境检测和桥接功能
454
+ - @kbapp/market-partner-sdk: 提供开吧商城接入jssdk
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @description 开吧埋点核心工具类(基于 Gsido 封装)
3
+ * @class DataAnalysis
4
+ * @example
5
+ * // ========== 第一步:导入并初始化埋点实例(建议全局唯一) ==========
6
+ * import { DataAnalysis } from '@kbapp/data-analysis';
7
+ *
8
+ * const kbTracker = new DataAnalysis({
9
+ * sdkUrl: 'https://page.kaiba315.com.cn/js/gsido-h5-min-1.0.7.1_final.js',
10
+ * appid: '由开吧分配',
11
+ * debugger: false, // 开发环境可设为 true,开启埋点日志输出
12
+ * });
13
+ *
14
+ * // ========== 第二步:设置全局公共上报属性(全局生效,仅需调用一次) ==========
15
+ * kbTracker.setReportGlobalAttrs({
16
+ * userId: '123456', // 用户唯一标识
17
+ * platform: 'h5', // 平台类型(h5/ios/android)
18
+ * appVersion: '1.0.0', // APP版本号
19
+ * });
20
+ *
21
+ * // ========== 第三步:普通事件埋点上报 ==========
22
+ * kbTracker.report({
23
+ * name: 'page_view', // 事件名称
24
+ * params: { // 上报的数据
25
+ * stayTime: 1000
26
+ * },
27
+ * });
28
+ */
29
+ export declare class DataAnalysis {
30
+ /** 是否开启调试模式 */
31
+ private debugger;
32
+ constructor(params: {
33
+ /** 由于埋点sdk过大, 所以通过sdkUrl动态加载 */
34
+ sdkUrl: string;
35
+ /** 埋点应用id, 由开吧分配 */
36
+ appid: string;
37
+ /** 是否开启调试模式 */
38
+ debugger?: boolean;
39
+ });
40
+ /** 打印日志 */
41
+ private log;
42
+ /**
43
+ *
44
+ * @description 为了保留 { get userId() { return 'xx' } } 的用法, 采用数组的形式
45
+ */
46
+ private globalAttrs;
47
+ /**
48
+ *
49
+ * @description 获取用于上报的属性 (合并公共属性)
50
+ */
51
+ private getReportDataMergeGlobalAttrs;
52
+ /**
53
+ *
54
+ * @description 获取原始 GsIdo 对象
55
+ */
56
+ getGsido(): typeof GsIdo | undefined;
57
+ /**
58
+ *
59
+ * @description 设置上报的公共属性
60
+ */
61
+ setReportGlobalAttrs(attrs?: {}): void;
62
+ /**
63
+ *
64
+ * @description 上报事件
65
+ */
66
+ report(params: {
67
+ name: string;
68
+ params?: Record<string, any>;
69
+ }): void;
70
+ /**
71
+ *
72
+ * @description 持续类型事件上报 - 开始事件
73
+ */
74
+ reportBeginEvent(params: {
75
+ name: string;
76
+ params?: Record<string, any>;
77
+ }): void;
78
+ /**
79
+ *
80
+ * @description 持续类型事件上报 - 结束事件
81
+ */
82
+ reportEndEvent(params: {
83
+ name: string;
84
+ params?: Record<string, any>;
85
+ }): void;
86
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 过滤对象第一层中值为 undefined 的属性(不处理嵌套对象)
3
+ * @param obj 待过滤的对象(仅支持纯对象,不支持数组/非对象类型)
4
+ * @returns 过滤后的新对象(自动剔除值为 undefined 的属性)
5
+ */
6
+ export declare function filterUndefinedProperties<T extends Record<string, any>>(obj: T): Pick<T, {
7
+ [K in keyof T]: T[K] extends undefined ? never : K;
8
+ }[keyof T]>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 加载script
3
+ * @param {object} params
4
+ * @param {string} params.src js url
5
+ * @param {string} [params.key]
6
+ */
7
+ export declare const loadScript: <Result>(params: {
8
+ src: string;
9
+ key: string;
10
+ }) => Result | Promise<Result>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ *
3
+ * @description 对象转map
4
+ */
5
+ export declare function objectToMap(params: Record<string, any>): Map<string, any>;
@@ -0,0 +1,3 @@
1
+ export * from './data-analysis';
2
+ export * from './models/DocActionEvent';
3
+ export * from './models/DocVisitEvent';