wgt-node-utils 1.2.45 → 1.2.46

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wgt-node-utils",
3
- "version": "1.2.45",
3
+ "version": "1.2.46",
4
4
  "description": "WGT工具类包",
5
5
  "main": "dist/bundle.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -17,8 +17,8 @@ class wgtNodeUtils {
17
17
  this.sendFeiShuMessageMap = {};
18
18
  // 是否發送错误信息开关
19
19
  this.filesErrorSendStatus = false;
20
- // 初始化Lark客户端
21
- if (appId && appSecret) {
20
+ // 初始化Lark客户端
21
+ if (appId && appSecret) {
22
22
  this.initClient(appId, appSecret);
23
23
  } else {
24
24
  console.error('Lark客户端初始化失败:未提供appId或appSecret');
@@ -57,7 +57,7 @@ class wgtNodeUtils {
57
57
  const cfAndroid = headers['cloudfront-is-android-viewer'];
58
58
  const cfTablet = headers['cloudfront-is-tablet-viewer'];
59
59
  const cfMobile = headers['cloudfront-is-mobile-viewer'];
60
-
60
+
61
61
  let device = '';
62
62
  if (cfDesktop && cfDesktop === 'true') {
63
63
  device = 'PC';
@@ -71,12 +71,12 @@ class wgtNodeUtils {
71
71
  if (cfTablet && cfTablet === 'true') {
72
72
  device = 'Pad';
73
73
  }
74
-
74
+
75
75
  // 部分手机获取不到是Android还是IOS,统一使用Android
76
76
  if (!device && cfMobile && cfMobile === 'true') {
77
77
  device = 'Android';
78
78
  }
79
-
79
+
80
80
  if (!device) {
81
81
  const system = this.getSystem(headers['user-agent']);
82
82
  if (system.isPC) {
@@ -101,7 +101,7 @@ class wgtNodeUtils {
101
101
  isPhone: device === 'IOS',
102
102
  isTablet: device === 'Pad'
103
103
  };
104
-
104
+
105
105
  // 其它设备均为空的情况下,默认当前设置为pc
106
106
  if (!system.isAndroid && !system.isPhone && !system.isTablet) {
107
107
  system.isPC = true;
@@ -116,24 +116,24 @@ class wgtNodeUtils {
116
116
  */
117
117
  addCommonHeadersInfo = (res) => {
118
118
  // 增加头信息Content-Type, 在开启gzip时会用到
119
- res.setHeader('Content-Type','text/html; charset=utf-8');
119
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
120
120
 
121
121
  // 指定被允许iframe的域名
122
- res.setHeader('Content-Security-Policy','frame-ancestors https://*.enjoy4fun.com https://*.beesads.com');
122
+ res.setHeader('Content-Security-Policy', 'frame-ancestors https://*.enjoy4fun.com https://*.beesads.com');
123
123
 
124
124
  // 通知浏览器应该只通过 HTTPS 访问该站点,并且以后使用 HTTP 访问该站点的所有尝试都应自动重定向到 HTTPS
125
- res.setHeader('Strict-Transport-Security','max-age=63072000; includeSubDomains; preload');
125
+ res.setHeader('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
126
126
 
127
127
  // 指定客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定
128
- res.setHeader('X-Content-Type-Options','nosniff');
128
+ res.setHeader('X-Content-Type-Options', 'nosniff');
129
129
 
130
130
  // 针对版本 8 及以上的 Internet Explorer,指示浏览器不要直接在浏览器中打开下载
131
- res.setHeader('X-Download-Options','noopen');
131
+ res.setHeader('X-Download-Options', 'noopen');
132
132
 
133
133
  // 当前页的主题标记为观察对象
134
134
  // Topics API 的目的是为调用者(包括运行脚本的页面上的第三方广告技术或广告提供商)提供页面访问者当前可能感兴趣的粗粒度广告主题。
135
135
  // 这些主题将补充上下文来自当前页面的信号可以组合起来以帮助为访问者找到合适的广告。
136
- res.setHeader('Observe-Browsing-Topics','?1');
136
+ res.setHeader('Observe-Browsing-Topics', '?1');
137
137
  }
138
138
  /***
139
139
  * 获取siteId 通过hostname
@@ -148,7 +148,7 @@ class wgtNodeUtils {
148
148
  if (siteId) {
149
149
  return resolve(siteId);
150
150
  }
151
-
151
+
152
152
  axios.get(url, { params: { domain: hostname } }).then((res) => {
153
153
  let siteData = res.data.data;
154
154
  // 如果未获取到数据,使用enjoy4fun.com做为默认数据
@@ -164,6 +164,87 @@ class wgtNodeUtils {
164
164
  });
165
165
  });
166
166
  }
167
+ /***
168
+ * 获取 site相关配置
169
+ * @isMobile 是否为移动端
170
+ * @url 请求后端接口
171
+ * @hostname 网站 hostname
172
+ * @imgDomain 图片地址
173
+ * @creativeId widget creative Id
174
+ * @mobileZoneKeyList 手机端使用zoneKeyList
175
+ * @pcZoneKeyList PC端使用zoneKEyList
176
+ */
177
+ // TODO 还未开发完成
178
+ async getSiteConfigByHostname(isMobile, url, hostname, imgDomain, creativeId, buildName, mobileZoneKeyList = [], pcZoneKeyList = []) {
179
+ const params = {
180
+ domain: hostname,
181
+ creative_id: creativeId
182
+ }
183
+ return new Promise((resolve) => {
184
+ axios.get(url, { params }).then(res => {
185
+ let siteData = res.data.data;
186
+ // 如果未获取到数据,使用做为默认数据
187
+ if (!siteData) {
188
+ siteData = {
189
+ siteId: "site_12",
190
+ zoneMap: {
191
+ 'pad_bottom_300_250': "45330",
192
+ 'pad_bottom_336_280': "45326",
193
+ 'pc_bottom_728_90': "45320",
194
+ 'pc_right_300_250': "45321",
195
+ 'pc_right_300_600': "45322",
196
+ 'pc_right_300_250_2': "45324",
197
+ 'pc_left_160_600': "45323",
198
+ 'mobile_300_250_top': "45327",
199
+ 'mobile_300_250_mid': "45328",
200
+ 'mobile_300_600_bottom': "45329",
201
+ 'interstitial_pc': "45334",
202
+ 'interstitial_mobile': "45335",
203
+ 'pc_bottom_160_90': "45325",
204
+ 'pc_pad_walkthrough_336_280': "45319",
205
+ 'mobile_game': "45331",
206
+ 'pc_game': "45333",
207
+ 'pad_game': "45332",
208
+ 'sidewall': "47185"
209
+ },
210
+ theme: {
211
+ icon: '',
212
+ logo: '',
213
+ title: '',
214
+ bgLeftImg: '',
215
+ bgRightImg: '',
216
+ bgBottomImg: '',
217
+ }
218
+ }
219
+ }
220
+
221
+ // 通过设备清洗zoneKeyMap
222
+ const zoneKeyList = isMobile ? mobileZoneKeyList : pcZoneKeyList;
223
+ let zoneMapForDevice = {};
224
+ const zoneMap = siteData.zoneMap || {};
225
+ zoneKeyList.forEach(zoneKey => {
226
+ if (zoneMap[zoneKey]) {
227
+ zoneMapForDevice[zoneKey] = zoneMap[zoneKey];
228
+ }
229
+ });
230
+ siteData.zoneMap = zoneMapForDevice;
231
+
232
+ // 处理皮肤字段
233
+ const { icon, logo, title, bgLeftImg, bgRightImg, bgBottomImg, ...otherTheme } = siteData.theme || {};
234
+ siteData.theme = {
235
+ icon: icon ? `${imgDomain}/site_icon/${icon}` : `/${buildName}/favicon.ico`,
236
+ logo: logo ? `${imgDomain}/site_logo/${logo}` : `/${buildName}/assets/logo-small.svg`,
237
+ title: title || 'Enjoy4fun',
238
+ bgLeftImg: bgLeftImg ? `${imgDomain}/theme/${bgLeftImg}` : '/gamebridge-web/assets/bg-left-winter.png',
239
+ bgRightImg: bgRightImg ? `${imgDomain}/theme/${bgRightImg}` : '/gamebridge-web/assets/bg-right-winter.png',
240
+ bgBottomImg: bgBottomImg ? `${imgDomain}/theme/${bgBottomImg}` : '/gamebridge-web/assets/bg-bottom-winter.png',
241
+ ...otherTheme
242
+ }
243
+ resolve(siteData);
244
+ });
245
+ });
246
+ }
247
+
167
248
  /***
168
249
  * node启动时将静态资源读取到内存中
169
250
  * @buildName 打包名称
@@ -193,9 +274,9 @@ class wgtNodeUtils {
193
274
  });
194
275
 
195
276
  // 增加preact依赖
196
- this.fileContents['preact.min.js'] = fs.readFileSync(path.join(dirname, `../${buildName}/dist/preact.min.js`),'utf8');
277
+ this.fileContents['preact.min.js'] = fs.readFileSync(path.join(dirname, `../${buildName}/dist/preact.min.js`), 'utf8');
197
278
 
198
- console.log('静态资源列表:');
279
+ console.log('静态资源列表:');
199
280
 
200
281
  const f2eFileLoadStatus = Object.keys(this.fileContents).every((item) => {
201
282
  const file = this.fileContents[item];
@@ -214,12 +295,12 @@ class wgtNodeUtils {
214
295
  console.log('静态资源:读取结束');
215
296
  });
216
297
  };
217
- /***
218
- * node启动时将静态资源读取到内存中
219
- * @appId 打包名称
220
- * @appSecret 打包版本号
221
- *
222
- */
298
+ /***
299
+ * node启动时将静态资源读取到内存中
300
+ * @appId 打包名称
301
+ * @appSecret 打包版本号
302
+ *
303
+ */
223
304
  initClient = (appId, appSecret) => {
224
305
  if (!this.client) {
225
306
  this.client = new lark.Client({
@@ -241,14 +322,14 @@ class wgtNodeUtils {
241
322
  if (!useSendFeiShu) {
242
323
  return;
243
324
  }
244
- // 发送消息
245
- this.client.im.message.create({
325
+ // 发送消息
326
+ this.client.im.message.create({
246
327
  params: {
247
328
  receive_id_type: 'chat_id'
248
329
  },
249
330
  data: {
250
331
  receive_id: receive_id,
251
- msg_type: 'text',
332
+ msg_type: 'text',
252
333
  content: feiShuContent,
253
334
  uuid: ''
254
335
  }
@@ -283,7 +364,7 @@ class wgtNodeUtils {
283
364
  * }
284
365
  *
285
366
  */
286
- appendLog = (message, ENV, components, err, options = {} ) => {
367
+ appendLog = (message, ENV, components, err, options = {}) => {
287
368
  const {
288
369
  usePageUrl = false,
289
370
  req = null,
@@ -291,7 +372,7 @@ class wgtNodeUtils {
291
372
  useSendFeiShu = false
292
373
  } = options;
293
374
  try {
294
- let feiShuContent = `{"text":"<b>前端容器node报错</b>\\ncomponent: ${components}\\nenv: ${ENV}\\nmesssage: ${message}"}`
375
+ let feiShuContent = `{"text":"<b>前端容器node报错</b>\\ncomponent: ${components}\\nenv: ${ENV}\\nmesssage: ${message}"}`
295
376
  if (usePageUrl && req) {
296
377
  const pageUrl = new URL(req.originalUrl, `${req.protocol}://${req.get('host')}`).href;
297
378
  feiShuContent = `{"text":"<b>前端容器node报错</b>\\ncomponent: ${components}\\nenv: ${ENV}\\npageUrl: ${decodeURIComponent(pageUrl)}\\nmesssage: ${message}"}`
@@ -305,7 +386,7 @@ class wgtNodeUtils {
305
386
  console.error(`${message} [${err.config.method}]: ${err.config.url}`);
306
387
  // console.error(`request: {params: ${JSON.stringify(err.config.params)}, data: ${ err.config.data ? JSON.stringify(err.config.data) : ''}}`);
307
388
  // console.error(`response: ${JSON.stringify( this.safeStringify(err.response.data))}`);
308
-
389
+
309
390
  this.sendFeiShu(feiShuContent, receive_id, useSendFeiShu);
310
391
 
311
392
  } else {
@@ -321,13 +402,13 @@ class wgtNodeUtils {
321
402
  safeStringify = (obj) => {
322
403
  const seen = new WeakSet();
323
404
  return JSON.stringify(obj, (key, value) => {
324
- if (typeof value === 'object' && value !== null) {
325
- if (seen.has(value)) {
326
- return; // 忽略循环引用
405
+ if (typeof value === 'object' && value !== null) {
406
+ if (seen.has(value)) {
407
+ return; // 忽略循环引用
408
+ }
409
+ seen.add(value);
327
410
  }
328
- seen.add(value);
329
- }
330
- return value;
411
+ return value;
331
412
  });
332
413
  }
333
414
  /**
@@ -346,35 +427,36 @@ class wgtNodeUtils {
346
427
  /**
347
428
  * 用于渲染游戏卡列表,清理无用字段
348
429
  * @param list 清理数组
430
+ * @param need 需要的字段 [game_id,game_category]
349
431
  */
350
- clearGameCardListData = (list, options = {}) => {
351
- // 支持传入 option 参数,按需求进行字段过滤
352
- // options.fields: 指定需要输出的字段数组,如 ['id', 'name', 'icon']
353
- const defaultFields = [
354
- 'id', 'game_category', 'icon', 'path', 'name', 'icon_video', 'new', 'developer'
355
- ];
356
- const fields = Array.isArray(options.fields) && options.fields.length > 0 ? options.fields : defaultFields;
432
+ clearGameCardListData = (list, need=[]) => {
433
+ var result = {};
434
+ // 游戏卡片使用到的字段
357
435
  return list.map((item = {}) => {
358
- // 统一字段映射
359
- const mapping = {
360
- id: item.game_id,
361
- game_category: item.game_category,
362
- icon: item.base_icon,
363
- path: item.game_path,
364
- name: item.game_name,
365
- icon_video: item.icon_video,
366
- developer: item.developer,
367
- new: item.new ? true : undefined // 将false转换为undefined, 用于节省ssr生成的文本长度
368
- };
369
- // 只输出指定字段
370
- const result = {};
371
- fields.forEach(key => {
372
- if (Object.prototype.hasOwnProperty.call(mapping, key)) {
373
- result[key] = mapping[key];
436
+
437
+ if (need.length === 0) {
438
+ return {
439
+ id: item.game_id,
440
+ game_category: item.game_category,
441
+ icon: item.base_icon,
442
+ path: item.game_path,
443
+ name: item.game_name,
444
+ icon_video: item.icon_video,
445
+ new: item.new ? true : undefined // 将false转换为undefined, 用于节省ssr生成的文本长度
374
446
  }
375
- });
376
- return result;
447
+ } else {
448
+ for (var i of need) {
449
+ result[i] = item[i] ? item[i] : '';
450
+ }
451
+ result.name = item.game_name || "";
452
+ result.id = item.game_id || "";
453
+ result.icon = item.base_icon || "";
454
+ result.path = item.game_path || "";
455
+ return result;
456
+ }
457
+
377
458
  });
459
+
378
460
  }
379
461
 
380
462
  // 用于渲染游戏详情的数据,清理无用字段
@@ -394,8 +476,8 @@ class wgtNodeUtils {
394
476
  let categoryBgColor = '';
395
477
  const categorys = game.categorys.map((item = {}) => {
396
478
  // 抽取第一个存在背景配置的分类
397
- if (!categoryBg.bg_left && !categoryBg.bg_right && !categoryBg.bg_bottom && item.bg_img) {
398
- const bgImg = item.bg_img || {};
479
+ if (!categoryBg.bg_left && !categoryBg.bg_right && !categoryBg.bg_bottom && item.bg_img) {
480
+ const bgImg = item.bg_img || {};
399
481
  categoryBg = {
400
482
  bg_left: bgImg.bg_left ? `${imgDomain}/${bgImg.bg_left}` : '',
401
483
  bg_right: bgImg.bg_right ? `${imgDomain}/${bgImg.bg_right}` : '',
@@ -506,9 +588,9 @@ class wgtNodeUtils {
506
588
  path: path,
507
589
  method: 'GET'
508
590
  };
509
-
591
+
510
592
  const req = https.request(options, (res) => {
511
- console.log(res.statusCode,'状态码')
593
+ console.log(res.statusCode, '状态码')
512
594
  // 如果状态码为 200,则说明域名可访问
513
595
  if (res.statusCode === 200) {
514
596
  resolve(true);
@@ -516,13 +598,13 @@ class wgtNodeUtils {
516
598
  resolve(false);
517
599
  }
518
600
  });
519
-
601
+
520
602
  req.on('error', (error) => {
521
603
  // 发生错误,说明域名不可访问
522
- console.log(error,'错误信息')
604
+ console.log(error, '错误信息')
523
605
  resolve(false);
524
606
  });
525
-
607
+
526
608
  req.end();
527
609
  });
528
610
  }
@@ -553,13 +635,13 @@ class wgtNodeUtils {
553
635
  gameDomain = GAME_DEFAULT_DOMAIN;
554
636
  }
555
637
  }
556
-
638
+
557
639
  // 当前游戏domain 为默认游戏域名
558
640
  if (gameDomain === GAME_DEFAULT_DOMAIN) {
559
- console.log(new Date(), 'gameResourcesMap:存在且等于默认游戏名使用默认link', this.gameResourcesMap,'link', link);
641
+ console.log(new Date(), 'gameResourcesMap:存在且等于默认游戏名使用默认link', this.gameResourcesMap, 'link', link);
560
642
  return link;
561
643
  }
562
-
644
+
563
645
  // 替换游戏链接
564
646
  if (ENV.includes('prod') || ENV.includes('qa')) {
565
647
  gameLink = link.replace(GAME_DEFAULT_DOMAIN, gameDomain);
@@ -570,7 +652,7 @@ class wgtNodeUtils {
570
652
  console.log(error, 'ReplaceGameResourcesError')
571
653
  gameLink = link;
572
654
  }
573
-
655
+
574
656
  return gameLink;
575
657
  };
576
658
  /**
@@ -653,7 +735,7 @@ class wgtNodeUtils {
653
735
 
654
736
  // 预定义的正则表达式(忽略大小写匹配敏感关键词)
655
737
  const regex = /\.(php|env|xml|production|example)/i;
656
- // 转为小写后检查是否匹配
738
+ // 转为小写后检查是否匹配
657
739
  return regex.test(path.toLowerCase());
658
740
  }
659
741
 
@@ -678,7 +760,7 @@ class wgtNodeUtils {
678
760
  const hasSpecialChar = /[^a-zA-Z0-9/_-]/;
679
761
 
680
762
 
681
- // 任意条件满足即为非法路径
763
+ // 任意条件满足即为非法路径
682
764
  return (
683
765
  illegalPatterns.test(path) || // 检测非法文件扩展或关键词
684
766
  hasUpperCase.test(path) || // 检测大写字母
@@ -695,7 +777,7 @@ class wgtNodeUtils {
695
777
  * @param {boolean} option.useSendFeiShu - 是否需要发送飞书
696
778
  * @returns {string} - SDK JS字符串
697
779
  */
698
- getSdkF2eFiles = async(adsTagHref, ENV, option) => {
780
+ getSdkF2eFiles = async (adsTagHref, ENV, option) => {
699
781
  const {
700
782
  components = '容器名称',
701
783
  receive_id = 'oc_aba13955509035daa7a799f30b1b3341',
@@ -705,8 +787,8 @@ class wgtNodeUtils {
705
787
  // // 生产环境使用API_PATH,其他环境使用adsTagHref
706
788
  // const sdkFilesPath = ENV === 'prod' ? `${API_PATH}/sdk?kaimen=08E28C7EEED6A1B3F9A80154D75A150B` : adsTagHref;
707
789
  // 飞书内容
708
- const feiShuContent = `{"text":"<b>前端容器node报错</b>\\ncomponent: ${components}\\nenv: ${ENV}\\nmesssage: SDK获取失败"}`;
709
-
790
+ const feiShuContent = `{"text":"<b>前端容器node报错</b>\\ncomponent: ${components}\\nenv: ${ENV}\\nmesssage: SDK获取失败"}`;
791
+
710
792
  try {
711
793
  const res = await axios.get(adsTagHref);
712
794
  return res.data;
@@ -739,7 +821,7 @@ class wgtNodeUtils {
739
821
  let languageCode = (acceptLanguage ? acceptLanguage.split(',')[0].split('-')[0].toLowerCase() : LANGUAGE_CODE_LIST[0].code) || (countryCode && countryCode.toLowerCase());
740
822
  // 如果都没有,则使用默认的语言代码列表中的第一个语言代码
741
823
  return LANGUAGE_CODE_LIST.some(item => item.code === languageCode) ? languageCode : LANGUAGE_CODE_LIST[0].code;
742
-
824
+
743
825
  }
744
826
 
745
827
  /**
@@ -755,7 +837,7 @@ class wgtNodeUtils {
755
837
  return new Promise((resolve) => {
756
838
  axios.get(url).then(res => {
757
839
  let siteData;
758
-
840
+
759
841
  if (type === 'content') {
760
842
  siteData = res.data && res.data.data && res.data.data;
761
843
  } else if (type === 'novel') {
@@ -767,7 +849,7 @@ class wgtNodeUtils {
767
849
  if (!siteData) {
768
850
  siteData = ['en'];
769
851
  }
770
-
852
+
771
853
  resolve(this.formatLanguageCodeList(siteData));
772
854
  }).catch(err => {
773
855
  resolve(this.formatLanguageCodeList(['en']));