drgame-cc 1.0.49 → 1.0.52

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.
@@ -2,11 +2,15 @@
2
2
  * 数据上报模块 - 统一封装层
3
3
  *
4
4
  * 内部使用 supersetLewo 上报脚本,对外提供简洁的调用接口:
5
- * Reporter.init(config) — 初始化(设置项目编码、游戏ID等公共字段)
6
- * Reporter.report(data) — 单次上报
7
- * Reporter.reportBatch(list) — 批量上报
8
- * Reporter.createDeviceId() — 获取/生成设备ID
9
- * Reporter.resetDeviceId() — 重置设备ID
5
+ * Reporter.init(config) — 初始化
6
+ * Reporter.report(data, immediate) — 单次上报(默认加入队列批量发送)
7
+ * Reporter.reportBatch(list) — 批量上报
8
+ * Reporter.flushQueue() — 立即刷新队列
9
+ * Reporter.reportAppStart() — 启动事件
10
+ * Reporter.reportSwitchBackground() — 切后台事件
11
+ * Reporter.reportSwitchBack() — 切回事件
12
+ * Reporter.reportAppExit() — 退出事件(自动计算游戏时长)
13
+ * Reporter.updateUserInfo(info) — 登录后更新用户信息
10
14
  */
11
15
 
12
16
  var supersetLewo = require('./superset-lewo');
@@ -20,8 +24,118 @@ var ActionType = {
20
24
  Exposure: '曝光',
21
25
  /** 点击 */
22
26
  Click: '点击',
27
+ /** 开始播放 */
28
+ StartPlay: '开始播放',
29
+ /** 结束播放(需上报时长 action_value) */
30
+ EndPlay: '结束播放',
31
+ /** 分享 */
32
+ Share: '分享',
33
+ /** 订购(需上报成功订购金额) */
34
+ Order: '订购',
35
+ /** 启动 */
36
+ Start: '启动',
37
+ /** 退出 */
38
+ Exit: '退出',
39
+ /** 切后台 */
40
+ SwitchBackground: '切后台',
41
+ /** 切回 */
42
+ SwitchBack: '切回',
23
43
  };
24
44
 
45
+ // ────────────────────────────────────────
46
+ // 内部队列管理(无需修改 supersetLewo)
47
+ // ────────────────────────────────────────
48
+
49
+ /** 配置接口地址 */
50
+ var CONFIG_URL = 'https://sup.daoran.tv/bi-api/api/config/get';
51
+
52
+ /** 事件队列 */
53
+ var _eventQueue = [];
54
+ /** 定时器句柄 */
55
+ var _batchTimer = null;
56
+ /** 每批最大条数 */
57
+ var _perNum = 10;
58
+ /** 发送间隔(秒) */
59
+ var _spaceSec = 30;
60
+ /** 队列模式是否已启用 */
61
+ var _queueEnabled = false;
62
+
63
+ /** 会话启动时间戳(毫秒),用于计算游戏时长 */
64
+ var _sessionStartTime = 0;
65
+
66
+ /** 额外用户信息(登录后填充,合并到上报 user 对象) */
67
+ var _extraUserInfo = {};
68
+
69
+ /**
70
+ * 修补 supersetLewo.getUserInfo,使登录后的额外字段能合并到 user 对象
71
+ * 避免修改 superset-lewo.js 源文件
72
+ */
73
+ (function _patchGetUserInfo() {
74
+ var originalGetUserInfo = supersetLewo.getUserInfo;
75
+ supersetLewo.getUserInfo = function () {
76
+ var info = originalGetUserInfo();
77
+ // 合并额外字段(如 user_id、user_type 等)
78
+ for (var key in _extraUserInfo) {
79
+ if (_extraUserInfo.hasOwnProperty(key)) {
80
+ info[key] = _extraUserInfo[key];
81
+ }
82
+ }
83
+ return info;
84
+ };
85
+ })();
86
+
87
+ /**
88
+ * 刷新队列 —— 将队列中所有事件打包发送
89
+ */
90
+ function _flushQueue() {
91
+ if (_eventQueue.length === 0) return;
92
+ var batch = _eventQueue.splice(0, _perNum);
93
+ supersetLewo.batchReporting(batch);
94
+ }
95
+
96
+ /**
97
+ * 添加单条事件到队列
98
+ */
99
+ function _addToQueue(eventItem) {
100
+ _eventQueue.push(eventItem);
101
+ if (_eventQueue.length >= _perNum) {
102
+ _flushQueue();
103
+ }
104
+ }
105
+
106
+ /**
107
+ * 批量添加事件到队列
108
+ */
109
+ function _addBatchToQueue(eventList) {
110
+ if (!Array.isArray(eventList) || eventList.length === 0) return;
111
+ for (var i = 0; i < eventList.length; i++) {
112
+ _eventQueue.push(eventList[i]);
113
+ }
114
+ if (_eventQueue.length >= _perNum) {
115
+ _flushQueue();
116
+ }
117
+ }
118
+
119
+ /**
120
+ * 启用队列定时刷新
121
+ */
122
+ function _startQueueTimer() {
123
+ if (_queueEnabled) return;
124
+ _queueEnabled = true;
125
+ _batchTimer = setInterval(_flushQueue, _spaceSec * 1000);
126
+ }
127
+
128
+ /**
129
+ * 停止队列定时刷新
130
+ */
131
+ function _stopQueueTimer() {
132
+ _queueEnabled = false;
133
+ if (_batchTimer) {
134
+ clearInterval(_batchTimer);
135
+ _batchTimer = null;
136
+ }
137
+ }
138
+
25
139
  // ────────────────────────────────────────
26
140
  // Reporter 实现
27
141
  // ────────────────────────────────────────
@@ -33,6 +147,40 @@ var Reporter = {
33
147
  /** 公共字段缓存(初始化时设置,每次上报自动合并) */
34
148
  _commonInfo: {},
35
149
 
150
+ /**
151
+ * 从后端获取批量上报配置
152
+ * @param {Function} [callback] - 回调函数,接收 { perNum, spaceSec }
153
+ */
154
+ fetchReportConfig: function (callback) {
155
+ var self = this;
156
+ supersetLewo.ajax({
157
+ url: CONFIG_URL,
158
+ type: 'get',
159
+ dataType: 'json',
160
+ data: {},
161
+ success: function (xhr, rsp) {
162
+ if (rsp && rsp.code === 200 && rsp.data) {
163
+ var cfg = rsp.data;
164
+ _perNum = cfg.perNum || 10;
165
+ _spaceSec = cfg.spaceSec || 30;
166
+ if (typeof callback === 'function') {
167
+ callback({ perNum: _perNum, spaceSec: _spaceSec });
168
+ }
169
+ } else {
170
+ if (typeof callback === 'function') {
171
+ callback({ perNum: 10, spaceSec: 30 });
172
+ }
173
+ }
174
+ },
175
+ error: function (xhr, rsp) {
176
+ console.warn('[Reporter] fetchReportConfig failed, use defaults');
177
+ if (typeof callback === 'function') {
178
+ callback({ perNum: 10, spaceSec: 30 });
179
+ }
180
+ }
181
+ });
182
+ },
183
+
36
184
  /**
37
185
  * 初始化上报模块
38
186
  * @param {import('../types/interfaces').IReporterConfig} config
@@ -69,33 +217,46 @@ var Reporter = {
69
217
  }
70
218
 
71
219
  supersetLewo.initUserInfo({
72
- os_type: "", // 系统类型安卓
73
- os_version: "", // 安卓版本15
74
- app_version: "1.0.0", // APP版本号
75
- app_item: config.app_item, // 渠道编码
76
- app_name: config.content_title, // APP展示名称
77
- app_project: config.content_id, // 产品内部编码
78
- province: "", // 省份编码
79
- city: "", // 城市编码
80
- uid: "", // 登录用户UID,未登录填空""
81
- user_id: "", // 会员/游客ID,无则填空""
82
- device_id: this._commonInfo.device_id, // 设备唯一ID,没有或不传则自动生成
83
- device_brand: "", // 手机品牌小写
84
- device_model: "", // 手机完整型号
85
- network_type: "", // 蜂窝流量网络
86
- carrier: "" // 运营商
87
- // device_id 不传,内部自动生成UUID填充,无需手动传入
220
+ os_type: config.os_type || "", // 操作系统类型 android/ios
221
+ os_version: config.os_version || "", // 操作系统版本号
222
+ app_version: config.app_version || "1.0.0", // APP版本号
223
+ app_item: config.app_item || "", // 渠道编码(项目编码)
224
+ app_name: config.app_name || config.content_title || "", // APP名称
225
+ app_project: config.app_project || config.content_id || "", // 产品编码
226
+ province: config.province || "", // 省份编码
227
+ city: config.city || "", // 城市编码
228
+ uid: config.uid || "", // 注册登录用户全局UID;游客/未登录填空字符串
229
+ user_id: config.user_id || "", // 会员ID(memberId),无则填空字符串,不用uid填充
230
+ device_id: this._commonInfo.device_id, // 设备唯一ID
231
+ device_brand: config.device_brand || "", // 设备品牌,小写
232
+ device_model: config.device_model || "", // 设备型号
233
+ network_type: config.network_type || "", // 网络类型:wifi/cellular
234
+ carrier: config.carrier || "", // 运营商
235
+ promotion_flag: config.promotion_flag || "0", // 推广标识(ubp接口获取,1推广/0自然)
236
+ user_type: config.user_type || "0" // 用户身份类型(0游客/1注册用户/2付费用户)
88
237
  });
89
238
 
90
239
  this._initialized = true;
240
+
241
+ // 记录启动时间
242
+ _sessionStartTime = Date.now();
243
+
244
+ // 异步拉取批量配置,拉取成功后启动队列
245
+ var self = this;
246
+ this.fetchReportConfig(function (batchCfg) {
247
+ _startQueueTimer();
248
+ console.log('[Reporter] Batch config:', batchCfg, '- Queue mode enabled');
249
+ });
250
+
91
251
  console.log('[Reporter] Initialized, reportUrl:', supersetLewo.config.reportUrl);
92
252
  },
93
253
 
94
254
  /**
95
255
  * 单次上报
96
- * @param {import('../types/interfaces').IReportItem} data - 上报数据(下划线格式)
256
+ * @param {import('../types/interfaces').IReportItem} data - 上报数据
257
+ * @param {boolean} [immediate=false] - 是否立即发送(不经过队列)
97
258
  */
98
- report: function (data) {
259
+ report: function (data, immediate) {
99
260
  if (!this._initialized) {
100
261
  console.warn('[Reporter] Not initialized. Call Reporter.init() first.');
101
262
  return;
@@ -120,15 +281,22 @@ var Reporter = {
120
281
  merged.device_id = supersetLewo.createDeviceId();
121
282
  }
122
283
 
123
- supersetLewo.superBatchReport(merged);
284
+ if (immediate) {
285
+ // 立即发送(生命周期事件等需要及时上报的场景)
286
+ supersetLewo.superBatchReport(merged);
287
+ } else {
288
+ // 加入队列,凑批次后批量发送
289
+ _addToQueue(merged);
290
+ }
124
291
  },
125
292
 
126
293
  /**
127
294
  * 批量上报
128
- * @param {Array<import('../types/interfaces').IReportItem>} dataList - 上报数据列表(下划线格式)
129
- * @param {import('../types/interfaces').IReportItem} [commonInfo] - 可选公共字段(覆盖初始化的公共字段)
295
+ * @param {Array<import('../types/interfaces').IReportItem>} dataList - 上报数据列表
296
+ * @param {import('../types/interfaces').IReportItem} [commonInfo] - 可选公共字段
297
+ * @param {boolean} [immediate=false] - 是否立即发送(不经过队列)
130
298
  */
131
- reportBatch: function (dataList, commonInfo) {
299
+ reportBatch: function (dataList, commonInfo, immediate) {
132
300
  if (!this._initialized) {
133
301
  console.warn('[Reporter] Not initialized. Call Reporter.init() first.');
134
302
  return;
@@ -158,7 +326,122 @@ var Reporter = {
158
326
  mergedCommon.device_id = supersetLewo.createDeviceId();
159
327
  }
160
328
 
161
- supersetLewo.batchReporting(dataList, mergedCommon);
329
+ // 合并公共字段到各事件中
330
+ var items = [];
331
+ for (var i = 0; i < dataList.length; i++) {
332
+ var item = {};
333
+ for (key in mergedCommon) {
334
+ if (mergedCommon.hasOwnProperty(key)) {
335
+ item[key] = mergedCommon[key];
336
+ }
337
+ }
338
+ for (key in dataList[i]) {
339
+ if (dataList[i].hasOwnProperty(key)) {
340
+ item[key] = dataList[i][key];
341
+ }
342
+ }
343
+ items.push(item);
344
+ }
345
+
346
+ if (immediate) {
347
+ // 立即发送
348
+ supersetLewo.batchReporting(items);
349
+ } else {
350
+ // 加入队列
351
+ _addBatchToQueue(items);
352
+ }
353
+ },
354
+
355
+ /**
356
+ * 立即刷新队列,将队列中所有事件立即发送
357
+ */
358
+ flushQueue: function () {
359
+ _flushQueue();
360
+ },
361
+
362
+ /**
363
+ * 上报「启动」事件 - APP启动成功后调用,记录启动时间
364
+ */
365
+ reportAppStart: function () {
366
+ _sessionStartTime = Date.now();
367
+ this.report({
368
+ element_position: "AppLaunch",
369
+ position_name: "应用启动",
370
+ element_type: "page",
371
+ element_name: "app_start",
372
+ action_type: ActionType.Start,
373
+ action_value: ""
374
+ }, true);
375
+ },
376
+
377
+ /**
378
+ * 上报「切后台」事件 - APP切到后台时调用
379
+ * 计算当前时间与启动时间差,action_value传时间差(秒)
380
+ */
381
+ reportSwitchBackground: function () {
382
+ var duration = Math.floor((Date.now() - _sessionStartTime) / 1000);
383
+ this.report({
384
+ element_position: "AppBackground",
385
+ position_name: "应用切后台",
386
+ element_type: "page",
387
+ element_name: "app_switch_background",
388
+ action_type: ActionType.SwitchBackground,
389
+ action_value: String(duration)
390
+ }, true);
391
+ },
392
+
393
+ /**
394
+ * 上报「切回」事件 - APP从后台切回时调用,上报后更新启动时间
395
+ */
396
+ reportSwitchBack: function () {
397
+ this.report({
398
+ element_position: "AppForeground",
399
+ position_name: "应用切前台",
400
+ element_type: "page",
401
+ element_name: "app_switch_back",
402
+ action_type: ActionType.SwitchBack,
403
+ action_value: ""
404
+ }, true);
405
+ // 更新启动时间
406
+ _sessionStartTime = Date.now();
407
+ },
408
+
409
+ /**
410
+ * 上报「退出」事件 - APP退出前调用
411
+ * 计算当前时间与启动时间差,action_value传时间差(秒),给后台上传游戏时长
412
+ */
413
+ reportAppExit: function () {
414
+ // 先刷新队列中剩余事件
415
+ _flushQueue();
416
+
417
+ var duration = Math.floor((Date.now() - _sessionStartTime) / 1000);
418
+ this.report({
419
+ element_position: "AppExit",
420
+ position_name: "应用退出",
421
+ element_type: "page",
422
+ element_name: "app_exit",
423
+ action_type: ActionType.Exit,
424
+ action_value: String(duration)
425
+ }, true);
426
+ // 重置启动时间
427
+ _sessionStartTime = 0;
428
+ },
429
+
430
+ /**
431
+ * 更新用户信息(登录后调用,传入memberId等)
432
+ * @param {Object} userInfo - 用户信息,如 { user_id: 'nC650471', user_type: '1' }
433
+ */
434
+ updateUserInfo: function (userInfo) {
435
+ if (!userInfo) return;
436
+ // 更新公共字段(合并到 data 事件中)
437
+ this.setCommonInfo(userInfo);
438
+ // 更新额外用户信息(合并到上报的 user 对象中)
439
+ for (var key in userInfo) {
440
+ if (userInfo.hasOwnProperty(key)) {
441
+ _extraUserInfo[key] = userInfo[key];
442
+ }
443
+ }
444
+ console.log('[Reporter] updateUserInfo:', userInfo);
162
445
  },
163
446
 
164
447
  /**
@@ -214,4 +497,4 @@ var Reporter = {
214
497
  module.exports = {
215
498
  Reporter: Reporter,
216
499
  ActionType: ActionType,
217
- };
500
+ };
@@ -571,4 +571,4 @@ supersetLewo.resetDeviceId();
571
571
  // CommonJS 模块导出(不改动上方 IIFE 逻辑)
572
572
  if (typeof module !== 'undefined' && module.exports) {
573
573
  module.exports = supersetLewo;
574
- }
574
+ }
@@ -23,6 +23,7 @@ export declare enum AdEvent {
23
23
  Closed = 'closed',
24
24
  Reward = 'reward',
25
25
  Error = 'error',
26
+ Exit = 'exit',
26
27
  }
27
28
 
28
29
  /** 广告错误码(聚合层统一) */
@@ -62,4 +63,4 @@ export declare enum KeyCode {
62
63
  export declare enum KeyAction {
63
64
  Down = 'down',
64
65
  Up = 'up',
65
- }
66
+ }
@@ -36,6 +36,8 @@ const AdEvent = {
36
36
  Reward: 'reward',
37
37
  /** 广告失败 */
38
38
  Error: 'error',
39
+ /** 退出确认(原生层确认退出) */
40
+ Exit: 'exit',
39
41
  };
40
42
 
41
43
  /** 广告错误码(聚合层统一) */
@@ -108,4 +110,4 @@ module.exports = {
108
110
  DevicePlatform,
109
111
  KeyCode,
110
112
  KeyAction,
111
- };
113
+ };
@@ -75,31 +75,71 @@ export interface IReporterConfig {
75
75
  content_id?: string;
76
76
  /** 游戏名 */
77
77
  content_title?: string;
78
+ /** 操作系统类型 android/ios */
79
+ os_type?: string;
80
+ /** 操作系统版本号 */
81
+ os_version?: string;
82
+ /** APP版本号 */
83
+ app_version?: string;
84
+ /** APP名称 */
85
+ app_name?: string;
86
+ /** 产品编码 */
87
+ app_project?: string;
88
+ /** 省份编码 */
89
+ province?: string;
90
+ /** 城市编码 */
91
+ city?: string;
92
+ /** 注册登录用户全局UID;游客/未登录填空字符串 */
93
+ uid?: string;
94
+ /** 会员ID(memberId),无则填空字符串 */
95
+ user_id?: string;
96
+ /** 设备品牌,小写 */
97
+ device_brand?: string;
98
+ /** 设备型号 */
99
+ device_model?: string;
100
+ /** 网络类型:wifi/cellular */
101
+ network_type?: string;
102
+ /** 运营商 */
103
+ carrier?: string;
104
+ /** 推广标识(ubp接口获取,1推广/0自然) */
105
+ promotion_flag?: string;
106
+ /** 用户身份类型(0游客/1注册用户/2付费用户) */
107
+ user_type?: string;
78
108
  }
79
109
 
80
110
  /** 上报数据项(下划线字段格式) */
81
111
  export interface IReportItem {
82
- /** 用户唯一标识(需要用户登录,产生UID) */
83
- user_id?: string;
84
- /** 设备唯一标识(设备号,如果无,则需要生成) */
85
- device_id?: string;
86
- /** 渠道编码 */
87
- app_item?: string;
88
- /** 内容类型(游戏固定上报"游戏") */
89
- content_type?: string;
90
- /** 游戏 ID */
112
+ /** 产品定义元素位置编码 */
113
+ element_position?: string;
114
+ /** 元素位置中文名称 */
115
+ position_name?: string;
116
+ /** OMS后台页面编码,无则空 */
117
+ page_code?: string;
118
+ /** OMS后台页面名称,无则空 */
119
+ page_name?: string;
120
+ /** OMS后台楼层ID,无则空 */
121
+ floor_id?: string;
122
+ /** OMS后台楼层名称,无则空 */
123
+ floor_name?: string;
124
+ /** 元素类型枚举(page/vlist/plist/res/act/link等) */
125
+ element_type?: string;
126
+ /** 元素名称/标题 */
127
+ element_name?: string;
128
+ /** 最小颗粒度内容ID */
91
129
  content_id?: string;
92
- /** 游戏名 */
130
+ /** 最小颗粒度内容标题 */
93
131
  content_title?: string;
94
- /** 元素位置(埋点范围表对应的元素位置列) */
95
- element_position?: string;
96
- /** 行为类型:曝光 / 点击 */
132
+ /** 扩展属性1,补充附属信息 */
133
+ ext_attr1?: string;
134
+ /** 扩展属性2,补充附属ID */
135
+ ext_attr2?: string;
136
+ /** 行为枚举:曝光、点击、开始播放、结束播放、分享、订购、启动、退出、切后台 */
97
137
  action_type?: string;
98
- /** 具体事件名(通过元素位置和行为生成事件名字) */
138
+ /** 行为值,时长填秒数,订购填金额(单位:分);无时间跨度行为填空 */
139
+ action_value?: string;
140
+ /** 友盟需要上报的事件名(仅友盟使用) */
99
141
  event_name?: string;
100
- /** 广告请求 ID(仅广告相关事件需要) */
101
- ad_request_id?: string;
102
- /** 客户端事件时间(yyyy-MM-dd HH:mm:ss,不传则自动生成) */
142
+ /** 事件发生时间,格式 yyyy-MM-dd HH:mm:ss,不传则自动生成 */
103
143
  event_time?: string;
104
144
  }
105
145
 
@@ -282,6 +322,8 @@ export interface IAdSdkConfig {
282
322
  customAdapters?: IAdAdapter[];
283
323
  /** 全局事件监听 */
284
324
  onEvent?: (event: AdEvent, data: IAdEventData) => void;
325
+ /** 数据上报配置(不传则不上报) */
326
+ reporter?: IReporterConfig;
285
327
  }
286
328
 
287
329
  /** 聚合广告 SDK 主接口 */
@@ -330,4 +372,4 @@ export interface IAdSdk {
330
372
 
331
373
  /** 销毁 SDK */
332
374
  destroy(): void;
333
- }
375
+ }
@@ -1,17 +1,10 @@
1
1
 
2
2
  const { ccclass, property } = cc._decorator;
3
3
 
4
- @ccclass('BtnExtra')
5
- export class BtnExtra extends cc.Component {
6
- @property({
7
- type: cc.SpriteFrame,
8
- tooltip: '悬停状态图片'
9
- })
4
+ @ccclass
5
+ export default class BtnExtra extends cc.Component {
6
+ @property(cc.SpriteFrame)
10
7
  hoverSprite: cc.SpriteFrame = null;
11
-
12
- @property({
13
- type: cc.SpriteFrame,
14
- tooltip: '普通状态图片'
15
- })
8
+ @property(cc.SpriteFrame)
16
9
  normalSprite: cc.SpriteFrame = null;
17
10
  }