@conecli/cone-render 0.8.20-shop.177 → 0.8.20-shop.179

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.
@@ -1 +1 @@
1
- import Taro from '@tarojs/taro';
2
1
  isIosDevice,
3
2
  isAndroidDevice,
4
3
  isJdAndHarmonyDevice,
5
4
  isJdAndAndroidDevice,
6
5
  jdAppVersion,
7
6
  jdAppVersionStr,
8
7
  isString,
9
8
  isObject,
10
9
  serialize,
11
10
  dealNativePixelToCssPixel,
12
11
  isPc,
13
12
  BUSINESS_TYPE,
14
13
  SECTION_HOME_TAB_NAME_TYPE,
15
14
  SECTION_HOME_TAB_TYPE,
16
15
  WXAPP_BIZ_KEY,
17
16
  WX_BUSINESS_TYPE,
18
17
  MPAAS_CONFIG_APP_VERSION,
19
18
  MPAAS_CONFIG_APP_LOW_VERSION,
20
19
  WXAPP_BIZ_SHOP_LIGHT_KEY,
21
20
  LoadJsInitLoadEnvType,
22
21
  LoadJsInitLoadType,
23
22
  LoadJsInitTriggerType,
24
23
  TaroEventType,
25
24
  getSystemInfos,
26
25
  ipLoc_djd,
27
26
  sgmCustomReport,
28
27
  getTaroStorageKeyValue,
29
28
  setTaroStorage,
30
29
  const designWidth = 750;
31
30
  return (
32
31
  Math.ceil((((parseInt(String(size), 10) / 40) * 750) / designWidth) * 10000) / 10000 + 'rem'
33
32
  );
34
33
  abTestLabels: {},
35
34
  loginState: false,
36
35
  cookiesStr: '',
37
36
  userInfo: userPinKey,
38
37
  isJingGouMiniViewState: false,
39
38
  isJingxiMiniViewState: false,
40
39
  pageInfo: {
41
40
  wxBusinessType: WX_BUSINESS_TYPE.NO,
42
41
  address: '',
43
42
  addressCommaStr: '',
44
43
  un_area: '',
45
44
  vapptype: '1',
46
45
  pageType: 'home',
47
46
  isExposureState: false,
48
47
  moduleId: '',
49
48
  entrance: '',
50
49
  dataType: BUSINESS_TYPE.ONLINE,
51
50
  floorExposureInfo: {},
52
51
  floorVideInfo: {},
53
52
  productVideInfo: {},
54
53
  tabsLoadAllDataInfo: {
55
54
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: false,
56
55
  },
57
56
  updateShopInfosAllState: false,
58
57
  isVipShop: false,
59
58
  isJdShowNativeImmersivePlayer: false,
60
59
  ...shopConfig,
61
60
  pageScrollTop: 0,
62
61
  pageIdxHeightInfo: {
63
62
  list: [],
64
63
  },
65
64
  shopNavBarHeight: 0,
66
65
  },
67
66
  defaultQueryLogInfo: {
68
67
  sourceType: 'JDshop',
69
68
  sourceValue: '',
70
69
  moduleId: 'none',
71
70
  entrance: 'none',
72
71
  },
73
72
  sysInfo: {
74
73
  windowWidth: isPc ? 375 : 0,
75
74
  containerWidth: isPc ? 375 : 0,
76
75
  windowHeight: 0,
77
76
  netWorkType: '4g',
78
77
  jdBottomBarHeight: 0,
79
78
  jdNativeHeaderHeight: 0,
80
79
  isJdTabletDevice: false,
81
80
  isJdTabletLandscape: false,
82
81
  },
83
82
  queryInfo: {},
84
83
  shopInfo: {},
85
84
  openAppData: {},
86
85
  public info: CommonInterFace.BaseConfigInfo;
87
86
  public config: {
88
87
  [key: string]: any;
89
88
  };
90
89
  public lazyContainer: CommonInterFace.lazyContainer;
91
90
  public renderedIsvComponents: CommonInterFace.renderedIsvComponents;
92
91
  public rootEleNode: HTMLElement | null;
93
92
  public checkStatusAndLoginPromise: object | null;
94
93
  private jmfeRegisterStatePromise: Promise<any> | null;
95
94
  private jmfeRegisterState: boolean;
96
95
  public loadJsSdkList: Array<any>;
97
96
  public loadJsSdkListCachePromise: any;
98
97
  constructor(opt) {
99
98
  this.info = this._getConfig(opt);
100
99
  this.config = {};
101
100
  this.loadJsSdkList = [];
102
101
  this.loadJsSdkListCachePromise = {};
103
102
  this.lazyContainer = {
104
103
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: {
105
104
  appLazyContainerList: [],
106
105
  appLazyFinishContainerList: [],
107
106
  },
108
107
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_PROMOTION]]: {
109
108
  appLazyContainerList: [],
110
109
  appLazyFinishContainerList: [],
111
110
  },
112
111
  };
113
112
  this.renderedIsvComponents = {};
114
113
  this.rootEleNode = document.querySelector('body');
115
114
  this.checkStatusAndLoginPromise = null;
116
115
  this.jmfeRegisterStatePromise = null;
117
116
  this.loadOtherSdk();
118
117
  isJdApp && this.jmfeReayPromise();
119
118
  }
120
119
  _getConfig(opt) {
121
120
  return Object.assign({}, DefaultConfig, opt);
122
121
  }
123
122
 
124
123
  jmfeReayPromise(): Promise<any> {
125
124
  if (isJdApp) {
126
125
  if (this.jmfeRegisterState) {
127
126
  return Promise.resolve(true);
128
127
  } else {
129
128
  !this.jmfeRegisterStatePromise &&
130
129
  (this.jmfeRegisterStatePromise = new Promise((resolve, reject) => {
131
130
  ready('jmfe', 3000)
132
131
  .then(() => {
133
132
  window?.jmfe && window.jmfe.registerCode(JSSDK_APP_WEBVIEW_CODE);
134
133
  this.jmfeRegisterState = true;
135
134
  resolve(true);
136
135
  console.log('松果app内初始化注册jmfe认证完成');
137
136
  })
138
137
  .catch(() => {
139
138
  reject(false);
140
139
  });
141
140
  }));
142
141
  return this.jmfeRegisterStatePromise;
143
142
  }
144
143
  } else {
145
144
  return Promise.reject(false);
146
145
  }
147
146
  }
148
147
 
149
148
  getJdScreenSizeInfo() {
150
149
  return new Promise((resolve) => {
151
150
  this.jmfeReayPromise().then(() => {
152
151
  return Promise.race([
153
152
  window.jmfe.getScreenSize(),
154
153
  this.taskTimeoutPromise(() => {
155
154
  return {
156
155
  status: '-10',
157
156
  msg: '获取大屏信息2s超时',
158
157
  };
159
158
  }),
160
159
  ])
161
160
  .then((res) => {
162
161
  console.log('===获取app大屏信息====', res);
163
162
  const { status, data } = res;
164
163
  if (status === '0' && data) {
165
164
  const { sizeType, isLandscape, pageHeight, pageWidth } = data;
166
165
  const getPageInfo = dealNativePixelToCssPixel({
167
166
  pageWidth,
168
167
  pageHeight,
169
168
  });
170
169
  this.info.sysInfo.jdScreenSizeType = sizeType;
171
170
  this.info.sysInfo.isJdTabletDevice = window.screen?.width >= 720;
172
171
  this.info.sysInfo.isJdTabletLandscape = isLandscape === '1';
173
172
  console.log(
174
173
  '===计算是否是app大屏信息,需满足宽度最新720===',
175
174
  getPageInfo,
176
175
  '原始数据',
177
176
  data,
178
177
  );
179
178
  resolve(getPageInfo);
180
179
  } else {
181
180
  resolve(false);
182
181
  }
183
182
  })
184
183
  .catch((err) => {
185
184
  console.log('获取大屏信息异常', err);
186
185
  resolve(false);
187
186
  });
188
187
  });
189
188
  });
190
189
  }
191
190
 
192
191
  listenJdTabletScreenChange() {
193
192
  this.jmfeReayPromise().then(() => {
194
193
  try {
195
194
  console.log('初始化监听大屏信息变化', window.jmfe.listenDeviceScreenChange);
196
195
  window.jmfe.listenDeviceScreenChange((event) => {
197
196
  console.log(
198
197
  '监听app大屏信息变化,orientation为landscape表示横屏,multiScreen为1表示android端分屏',
199
198
  event,
200
199
  '通过前端判断是不是横屏',
201
200
  window.matchMedia('(orientation: landscape)')?.matches,
202
201
  );
203
202
  const { orientation } = event?.data;
204
203
  if (orientation) {
205
204
  this.info.sysInfo.isJdTabletLandscape = orientation === 'landscape';
206
205
  Taro.eventCenter.trigger(
207
206
  TaroEventType.TABLE_SCREEN_CHANGE,
208
207
  this.info.sysInfo.isJdTabletLandscape,
209
208
  orientation,
210
209
  );
211
210
  }
212
211
  });
213
212
  } catch (error) {
214
213
  console.log('listenScreenChange的打印error:', error);
215
214
  }
216
215
  });
217
216
  }
218
217
 
219
218
  updateBusinessDomainAndApi(domain, api) {
220
219
  }
221
220
 
222
221
  formatNativeScreenPageData(action) {
223
222
  let getChangePageInfo: any = null;
224
223
  try {
225
224
  const getNativeScreenPageInfoStr = window.XWebView?._callNative(
226
225
  JSON.stringify({
227
226
  plugin: 'JDHybridScreenPlugin',
228
227
  action,
229
228
  sync: '1',
230
229
  }),
231
230
  );
232
231
  const getChangePageInfoData =
233
232
  typeof getNativeScreenPageInfoStr === 'string'
234
233
  ? JSON.parse(getNativeScreenPageInfoStr)
235
234
  : null;
236
235
  if (getChangePageInfoData && typeof getChangePageInfoData === 'object') {
237
236
  const { code, data } = getChangePageInfoData;
238
237
  getChangePageInfo = code && code === '0' ? data : null;
239
238
  }
240
239
  } catch (e) {
241
240
  console.log('JDHybridScreenPlugin转换异常', e);
242
241
  }
243
242
  return getChangePageInfo;
244
243
  }
245
244
 
246
245
  isAndroidFoldScreen() {
247
246
  return this.formatNativeScreenPageData('isFoldScreen') === '1';
248
247
  }
249
248
 
250
249
  getJdAndroidPageChangeScreenInfo() {
251
250
  const getPageScreenInfo = this.formatNativeScreenPageData('getScreenSize');
252
251
  if (getPageScreenInfo && getPageScreenInfo?.pageWidth && getPageScreenInfo?.pageHeight) {
253
252
  const { pageWidth, pageHeight } = dealNativePixelToCssPixel({
254
253
  pageWidth: getPageScreenInfo.pageWidth,
255
254
  pageHeight: getPageScreenInfo.pageHeight,
256
255
  });
257
256
  getPageScreenInfo.pageWidth = pageWidth;
258
257
  getPageScreenInfo.pageHeight = pageHeight;
259
258
  }
260
259
  return getPageScreenInfo;
261
260
  }
262
261
 
263
262
  async getSystemInfo(params) {
264
263
  let info: UtilsInterFace.taroGetSystemInfoSyncRes | any = getSystemInfos(params);
265
264
  if (isJdAndAndroidDevice && info?.initWindowWidth <= 0) {
266
265
  let _isfoldScreen = false;
267
266
  const getStorageData = getTaroStorageKeyValue('jd_shopx_androidIsFoldScreen');
268
267
  console.info(
269
268
  '获取当前本地存储是否有jd_shopx_androidIsFoldScreen',
270
269
  getStorageData,
271
270
  '通过缓存值第一次判断是否是折叠屏',
272
271
  getStorageData === 'true',
273
272
  );
274
273
  if (!getStorageData) {
275
274
  _isfoldScreen = this.isAndroidFoldScreen();
276
275
  setTaroStorage('jd_shopx_androidIsFoldScreen', `${_isfoldScreen}`);
277
276
  } else {
278
277
  _isfoldScreen = getStorageData === 'true';
279
278
  }
280
279
  if (_isfoldScreen) {
281
280
  const getJdAndroidPageInfo = this.getJdAndroidPageChangeScreenInfo();
282
281
  if (getJdAndroidPageInfo) {
283
282
  info = getSystemInfos(getJdAndroidPageInfo);
284
283
  console.warn(
285
284
  '当前为松果安卓折叠屏app,获取折叠屏信息',
286
285
  getJdAndroidPageInfo,
287
286
  '获取转换后的系统信息',
288
287
  info,
289
288
  );
290
289
  sgmCustomReport({
291
290
  type: 2,
292
291
  code: 'android_jdapp_foldScreen_info',
293
292
  msg: {
294
293
  title: `松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异`,
295
294
  androidPageInfo: getJdAndroidPageInfo,
296
295
  jdAppVersionStr,
297
296
  taroSysInfo: info,
298
297
  },
299
298
  });
300
299
  }
301
300
  }
302
301
  }
303
302
  if (isJdApp) {
304
303
  info?.isJdTabletDevice && this.listenJdTabletScreenChange();
305
304
  }
306
305
  this.info.sysInfo = {
307
306
  actualNavBarHeight: 0,
308
307
  ...this.info.sysInfo,
309
308
  ...info,
310
309
  safeContentHeight: info?.screenHeight,
311
310
  headerHeight: 0,
312
311
  tabBarHeight: 0,
313
312
  };
314
313
  if (isJdApp) {
315
314
  this.info.sysInfo['hostVersionName'] = jdAppVersionStr;
316
315
  this.info.sysInfo['hostAppVersion'] = jdAppVersion;
317
316
  this.getAddressCachePromise();
318
317
  this.getElderModePromise();
319
318
  this.getJDAppearanceStatePromise();
320
319
  this.createJdAndroidRquestEventForTouchStart();
321
320
  }
322
321
  this.getWifiVideoAutoPlayAsync();
323
322
  this.getMPaasConfigAsync();
324
323
  this.getNetWorkType();
325
324
  }
326
325
 
327
326
  taskTimeoutPromise(callBack, timeout = 2000) {
328
327
  return new Promise((resolve) => {
329
328
  setTimeout(() => {
330
329
  const getCallBackRes = typeof callBack === 'function' && callBack();
331
330
  return resolve(getCallBackRes || false);
332
331
  }, timeout);
333
332
  });
334
333
  }
335
334
 
336
335
  getElderModePromise() {
337
336
  if (this.info.sysInfo.hasOwnProperty('jdAppModeType')) {
338
337
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
339
338
  } else {
340
339
  if (isJdAndAndroidDevice) {
341
340
  this.info.sysInfo.jdAppModeType = '0';
342
341
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
343
342
  } else {
344
343
  return Promise.race([
345
344
  this.taskTimeoutPromise(() => {
346
345
  this.info.sysInfo.jdAppModeType = '0';
347
346
  return this.info.sysInfo.jdAppModeType;
348
347
  }),
349
348
  new Promise((resolve) => {
350
349
  const getCallBackName = `getJdCurrentModeType${Date.now()}`;
351
350
  if (!window[getCallBackName]) {
352
351
  window[getCallBackName] = (res) => {
353
352
  try {
354
353
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
355
354
  const { status, data, msg } = getResJson;
356
355
  console.log(`获取松果app展示模式成功,返回结果${data}`);
357
356
  if (status === '0') {
358
357
  this.info.sysInfo.jdAppModeType = data;
359
358
  resolve(data);
360
359
  } else {
361
360
  resolve('0');
362
361
  }
363
362
  } catch (e) {
364
363
  resolve('0');
365
364
  }
366
365
  window[getCallBackName] = null;
367
366
  };
368
367
  }
369
368
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
370
369
  method: 'callSyncRouterModuleWithParams',
371
370
  params: JSON.stringify({
372
371
  routerURL: 'router://JDBModeModule/getCurrentMode',
373
372
  routerParam: {},
374
373
  callBackName: `window.${getCallBackName}`,
375
374
  callBackId: `${getCallBackName}Ios`,
376
375
  }),
377
376
  });
378
377
  }),
379
378
  ]);
380
379
  }
381
380
  }
382
381
  }
383
382
  getAPPUseStraightCorner() {
384
383
  const routerURL = 'router://JDBaseUtilsModule/isUI14Enable';
385
384
  const params = {
386
385
  routerURL,
387
386
  routerParam: {},
388
387
  jdRouter: '1',
389
388
  };
390
389
  if (this.info.sysInfo.hasOwnProperty('jdStraightCorner')) {
391
390
  return Promise.resolve(this.info.sysInfo.jdStraightCorner);
392
391
  } else {
393
392
  return this.jmfeReayPromise()
394
393
  .then(() => {
395
394
  if (isJdAndHarmonyDevice || !isJdApp) {
396
395
  console.log('not APP or is Harmony');
397
396
  return Promise.resolve(false);
398
397
  }
399
398
  console.log('jmfe setShareInfo', params);
400
399
  return Promise.race([
401
400
  window.jmfe.callRouter(params),
402
401
  this.taskTimeoutPromise(() => {
403
402
  return false;
404
403
  }),
405
404
  ]).then(({ status, data }) => {
406
405
  console.log('004 ~ file: index.tsx:133 ~ .then ~ data:', data);
407
406
  console.log('004 ~ file: index.tsx:133 ~ .then ~ status:', status);
408
407
  this.info.sysInfo.jdStraightCorner = status === '0' && Number(data) === 1;
409
408
  return Promise.resolve(status === '0' && Number(data) === 1);
410
409
  });
411
410
  })
412
411
  .catch((e) => {
413
412
  console.log('jmfe error', e);
414
413
  return Promise.resolve(false);
415
414
  });
416
415
  }
417
416
  }
418
417
 
419
418
  getJDAppearanceStatePromise() {
420
419
  if (this.info.sysInfo.hasOwnProperty('jdAppearanceState')) {
421
420
  return Promise.resolve(this.info.sysInfo.jdAppearanceState);
422
421
  } else {
423
422
  return Promise.race([
424
423
  this.taskTimeoutPromise(() => {
425
424
  this.info.sysInfo.jdAppearanceState = '0';
426
425
  return this.info.sysInfo.jdAppearanceState;
427
426
  }),
428
427
  new Promise((resolve) => {
429
428
  const getCallBackName = `getJdCurrentAppearanceState${Date.now()}`;
430
429
  if (!window[getCallBackName]) {
431
430
  window[getCallBackName] = (res) => {
432
431
  try {
433
432
  console.log('getJDAppearanceStatePromise', res);
434
433
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
435
434
  const { status, data, msg } = getResJson;
436
435
  console.log(`获取松果app是否开启黑暗模式成功,返回结果${data}`);
437
436
  if (status === '0') {
438
437
  this.info.sysInfo.jdAppearanceState = data;
439
438
  resolve(data);
440
439
  } else {
441
440
  resolve('0');
442
441
  }
443
442
  } catch (e) {
444
443
  resolve('0');
445
444
  }
446
445
  window[getCallBackName] = null;
447
446
  };
448
447
  }
449
448
  if (isAndroidDevice) {
450
449
  const jsonString = JSON.stringify({
451
450
  callBackName: `window.${getCallBackName}`,
452
451
  });
453
452
  console.log('window.JDAppearance', window.JDAppearance);
454
453
  window.JDAppearance && window.JDAppearance.getUiState(jsonString);
455
454
  } else {
456
455
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
457
456
  method: 'callSyncRouterModuleWithParams',
458
457
  params: JSON.stringify({
459
458
  routerURL: 'router://JDWebViewBusinessModule/getJDAppearanceState',
460
459
  routerParam: {},
461
460
  callBackName: `window.${getCallBackName}`,
462
461
  callBackId: `${getCallBackName}Ios`,
463
462
  }),
464
463
  });
465
464
  }
466
465
  }),
467
466
  ]);
468
467
  }
469
468
  }
470
469
 
471
470
  createJdAndroidRquestEventForTouchStart() {
472
471
  if (isJdAndAndroidDevice && window.JdAndroid) {
473
472
  const rootEleNode = document.querySelector('body');
474
473
  if (rootEleNode) {
475
474
  rootEleNode.addEventListener('touchstart', this.jdAndroidAddEventListenerTouchStart, false);
476
475
  }
477
476
  }
478
477
  }
479
478
  jdAndroidAddEventListenerTouchStart(e) {
480
479
  const isH5SwiperCustomEle = e?.target?.closest('.J_h5SwiperCustom');
481
480
  if (!isH5SwiperCustomEle) {
482
481
  const hasCustomEle = e
483
482
  ? e?.target?.closest('.J_customScroll') || e?.target?.closest('.J_customLayout')
484
483
  : false;
485
484
  if (!hasCustomEle) {
486
485
  window.JdAndroid.requestEvent(false);
487
486
  console.log(
488
487
  'createJdAndroidRquestEvent 所有松果安卓APP内的document touch start事件执行检测requestEvent并重置为false',
489
488
  );
490
489
  }
491
490
  }
492
491
  }
493
492
  removeJdAndroidRquestEventForTouchStart() {
494
493
  if (isJdAndAndroidDevice && window.JdAndroid) {
495
494
  const rootEleNode = document.querySelector('body');
496
495
  if (rootEleNode) {
497
496
  rootEleNode.removeEventListener(
498
497
  'touchstart',
499
498
  this.jdAndroidAddEventListenerTouchStart,
500
499
  false,
501
500
  );
502
501
  }
503
502
  }
504
503
  }
505
504
 
506
505
  getNetWorkType() {
507
506
  if (isJdApp) {
508
507
  this.jmfeReayPromise().then(() => {
509
508
  window.jmfe
510
509
  .getNetworkStatus()
511
510
  .then(({ status, data }) => {
512
511
  console.log('在app内初始化通过jmfe对象获取网络状态完成,当前网络状态====', data);
513
512
  if (status === '0') {
514
513
  this.info.sysInfo['netWorkType'] = data;
515
514
  } else {
516
515
  this._taroGetNetworkType();
517
516
  }
518
517
  })
519
518
  .catch((err) => {
520
519
  console.log('在app内初始化通过jmfe对象获取网络状态异常====', err);
521
520
  this._taroGetNetworkType();
522
521
  });
523
522
  });
524
523
  } else {
525
524
  this._taroGetNetworkType();
526
525
  }
527
526
  }
528
527
  _taroGetNetworkType() {
529
528
  Taro.getNetworkType().then((getRes) => {
530
529
  if (getRes && getRes.networkType) {
531
530
  this.info.sysInfo['netWorkType'] = getRes.networkType;
532
531
  console.log(
533
532
  '在app内通过taro对象获取网络状态完成,当前网络状态',
534
533
  this.info.sysInfo['netWorkType'],
535
534
  );
536
535
  }
537
536
  });
538
537
  }
539
538
 
540
539
  getCacheAddressRouter() {
541
540
  if (window.jmfe && isJdApp) {
542
541
  if (!isJdAndHarmonyDevice) {
543
542
  return Promise.race([
544
543
  window.jmfe.callRouter({
545
544
  jdRouter: '1',
546
545
  routerURL: isAndroidDevice
547
546
  ? 'router://JDAddressModule/getCacheAddress'
548
547
  : 'router://JDBAddressCacheManagerModule/getCacheAddress',
549
548
  routerParam: { sceneId: 'basicShoppingProcess' },
550
549
  }),
551
550
  this.taskTimeoutPromise(() => {
552
551
  return {
553
552
  status: '-1000',
554
553
  msg: '原生router协议获取地址信息超时',
555
554
  };
556
555
  }, 3000),
557
556
  ]);
558
557
  } else {
559
558
  return Promise.resolve({
560
559
  status: '-1001',
561
560
  msg: '鸿蒙系统调用jmfe异常,获取失败',
562
561
  });
563
562
  }
564
563
  } else {
565
564
  return Promise.resolve({
566
565
  status: '-1002',
567
566
  msg: 'jmfe不存在,获取失败',
568
567
  });
569
568
  }
570
569
  }
571
570
 
572
571
  getAddressCachePromise() {
573
572
  return new Promise((resolve) => {
574
573
  if (this?.info?.sysInfo?.lat && this?.info?.sysInfo?.lng && this?.info?.sysInfo?.area) {
575
574
  resolve({
576
575
  lat: this.info.sysInfo.lat,
577
576
  lng: this.info.sysInfo.lng,
578
577
  area: this?.info?.sysInfo?.area,
579
578
  });
580
579
  } else {
581
580
  this.jmfeReayPromise().then(() => {
582
581
  this.getCacheAddressRouter()
583
582
  .then((res) => {
584
583
  const { status, data } = res;
585
584
  console.log('原生端获取经纬度原始数据结果', status, data);
586
585
  if (status === '0' && data) {
587
586
  const { lat, latitude, lng, longitude, provinceId, cityId, countyId, townId } =
588
587
  data || {};
589
588
  let area = '';
590
589
  this.info.sysInfo['lat'] = `${lat || latitude || ''}`;
591
590
  this.info.sysInfo['lng'] = `${lng || longitude || ''}`;
592
591
  if (provinceId) {
593
592
  area = `${provinceId}_${cityId || 0}_${countyId || 0}_${townId || 0}`;
594
593
  this.info.pageInfo['address'] = area;
595
594
  this.info.pageInfo['addressCommaStr'] = area.replace(/_/g, ',');
596
595
  Taro.eventCenter.trigger(
597
596
  TaroEventType.USER_AREA_UPDATE,
598
597
  this.info.pageInfo.address,
599
598
  );
600
599
  }
601
600
  resolve({
602
601
  lat: this.info.sysInfo['lat'],
603
602
  lng: this.info.sysInfo['lng'],
604
603
  area: area,
605
604
  });
606
605
  } else {
607
606
  typeof res === 'object' &&
608
607
  sgmCustomReport({
609
608
  type: 3,
610
609
  code: 'jdapp_getCacheAddress_info',
611
610
  msg: {
612
611
  title: '松果app内通过router协议获取用户地址及经纬度信息异常',
613
612
  jdAppVersion: jdAppVersionStr,
614
613
  ...res,
615
614
  },
616
615
  });
617
616
  resolve({ lat: '', lng: '', area: '' });
618
617
  }
619
618
  })
620
619
  .catch((e) => {
621
620
  console.log(' ~~ file: index.h5.ts:518 ~~ .catch ~~ e:', e);
622
621
  resolve({ lat: '', lng: '', area: '' });
623
622
  console.log('判断jmfe不存在,获取经纬度信息异常');
624
623
  });
625
624
  });
626
625
  }
627
626
  });
628
627
  }
629
628
 
630
629
  async updateMPaasConfigAsync(isBeforePageReady: boolean) {
631
630
  console.log('updateMPaasConfigAsync isBeforePageReady:', isBeforePageReady);
632
631
  if (!isJdApp) {
633
632
  return;
634
633
  }
635
634
  const avifSwitch = await getMPaasConfigByBussinessKey('avifSwitch', isBeforePageReady);
636
635
  this.info.sysInfo.dynamicConfig['avifSwitch'] = avifSwitch;
637
636
  const hybridHttpSwitch = await getMPaasConfigByBussinessKey(
638
637
  'hybridHttpSwitch',
639
638
  isBeforePageReady,
640
639
  );
641
640
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = hybridHttpSwitch;
642
641
  const isFollowAppVideoPlayStatus = await getMPaasConfigByBussinessKey(
643
642
  'isFollowAppVideoPlayStatus',
644
643
  isBeforePageReady,
645
644
  );
646
645
  console.log(
647
646
  'isBeforePageReady:',
648
647
  isBeforePageReady,
649
648
  'isFollowAppVideoPlayStatus:',
650
649
  isFollowAppVideoPlayStatus,
651
650
  );
652
651
  if (isFollowAppVideoPlayStatus === true || isFollowAppVideoPlayStatus === 'true') {
653
652
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = true;
654
653
  }
655
654
  }
656
655
 
657
656
  async getWifiVideoAutoPlayAsync() {
658
657
  this.info.sysInfo['wifiVideoAutoPlay'] = false;
659
658
  if (!isJdApp) {
660
659
  return;
661
660
  }
662
661
  const videoPlayStatus = await getWifiVideoAutoPlay().catch((e) => {
663
662
  return 0;
664
663
  });
665
664
  if (Number(videoPlayStatus) === 1) {
666
665
  this.info.sysInfo['wifiVideoAutoPlay'] = true;
667
666
  }
668
667
  }
669
668
 
670
669
  async getMPaasConfigAsync() {
671
670
  this.info.sysInfo.dynamicConfig = {};
672
671
  this.info.sysInfo.dynamicConfig['avifSwitch'] = {};
673
672
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = {};
674
673
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = false;
675
674
  return this.updateMPaasConfigAsync(true);
676
675
  }
677
676
 
678
677
  getDynamicConfig(key: string) {
679
678
  return this.info.sysInfo.dynamicConfig[key];
680
679
  }
681
680
  async updateMPaasConfig() {
682
681
  console.log('updateMPaasConfig');
683
682
  if (
684
683
  isIosDevice &&
685
684
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_VERSION) < 0 &&
686
685
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_LOW_VERSION) >= 0
687
686
  ) {
688
687
  try {
689
688
  await this.updateMPaasConfigAsync(false);
690
689
  } catch (e) {
691
690
  console.log('updateMPaasConfigAsync:', e);
692
691
  }
693
692
  }
694
693
  }
695
694
 
696
695
  toLogin(options) {
697
696
  return this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState
698
697
  ? this.toWxAppLogin(options)
699
698
  : this.toWebLogin(options);
700
699
  }
701
700
 
702
701
  doLogin(options) {
703
702
  return this.toLogin(options);
704
703
  }
705
704
 
706
705
  doLoginForJdPin(options = {}) {
707
706
  return this.doLogin({
708
707
  loginColor: {
709
708
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
710
709
  dpin: 0,
711
710
  },
712
711
  ...options,
713
712
  });
714
713
  }
715
714
 
716
715
  toWebLogin(options) {
717
716
  let params: {
718
717
  returnurl: string;
719
718
  } = {
720
719
  returnurl: '',
721
720
  };
722
721
  const loginUrl = isPc
723
722
  ? `//passport.jd.com/new/login.aspx`
724
723
  : `${domain.mobileLogin}/user/login.action`;
725
724
  const defaultParams = {
726
725
  appid: '100',
727
726
  returnurl: window.location.href,
728
727
  };
729
728
  if (isString(options)) {
730
729
  params = Object.assign({}, defaultParams, {
731
730
  returnurl: options,
732
731
  });
733
732
  } else if (isObject(options)) {
734
733
  const { loginColor, ...otherOptions } = options;
735
734
  params = Object.assign({}, defaultParams, otherOptions);
736
735
  } else {
737
736
  params = defaultParams;
738
737
  }
739
738
  params.returnurl = encodeURIComponent(params.returnurl);
740
739
  let getFullUrl = loginUrl + '?' + serialize(params);
741
740
  if (isPc) {
742
741
  getFullUrl = getFullUrl.replace(/returnurl/, 'ReturnUrl');
743
742
  }
744
743
  return Promise.resolve({
745
744
  h5ToUrl: true,
746
745
  url: getFullUrl,
747
746
  }).then(() => {
748
747
  window.location.href = getFullUrl;
749
748
  });
750
749
  }
751
750
 
752
751
  toWxAppLogin(options = {}) {
753
752
  console.log('微信京购小程序中h5登录跳转', options);
754
753
  return Promise.resolve(true).then(() => {
755
754
  const { loginColor } = Object.assign(
756
755
  {},
757
756
  {
758
757
  loginColor: {
759
758
  biz: WXAPP_BIZ_KEY,
760
759
  dpin: 1,
761
760
  },
762
761
  },
763
762
  options,
764
763
  );
765
764
  window.location.href = `${domain.wq}/pinbind/pintokenredirect?biz=${
766
765
  loginColor.biz
767
766
  }&url=${encodeURIComponent(window.location.href)}`;
768
767
  });
769
768
  }
770
769
 
771
770
  getLoginCookie() {
772
771
  return Promise.resolve({
773
772
  pin: cookie.get('pin') || '',
774
773
  });
775
774
  }
776
775
 
777
776
  clearLoginCookie() {
778
777
  cookie.remove('pin');
779
778
  }
780
779
 
781
780
  checkStatusAndLogin(options = {}) {
782
781
  if (!this.checkStatusAndLoginPromise) {
783
782
  this.checkStatusAndLoginPromise = new Promise(async (resolve, reject) => {
784
783
  try {
785
784
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
786
785
  if (getLoginState) {
787
786
  resolve(true);
788
787
  } else {
789
788
  this.toLogin(options);
790
789
  reject(false);
791
790
  }
792
791
  } catch (e) {
793
792
  this.toLogin(options);
794
793
  reject(false);
795
794
  }
796
795
  });
797
796
  return this.checkStatusAndLoginPromise;
798
797
  } else {
799
798
  return this.checkStatusAndLoginPromise
800
799
  .then(() => {
801
800
  return Promise.resolve(true);
802
801
  })
803
802
  .catch(() => {
804
803
  this.toLogin(options);
805
804
  return Promise.reject(true);
806
805
  });
807
806
  }
808
807
  }
809
808
 
810
809
  checkJdStatusAndLogin(
811
810
  options = {
812
811
  loginColor: {
813
812
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
814
813
  dpin: 0,
815
814
  },
816
815
  },
817
816
  ) {
818
817
  return this.checkStatusAndLogin(options);
819
818
  }
820
819
 
821
820
  doCheckLoginStateAndForApiCheck(options) {
822
821
  if (this.info.loginState) {
823
822
  return Promise.resolve(true);
824
823
  } else {
825
824
  return new Promise((resolve, reject) => {
826
825
  if (this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState) {
827
826
  const getWqAuthToken = cookie.get('wq_auth_token');
828
827
  const getWqSkey = cookie.get('wq_skey');
829
828
  const getWqUin = cookie.get('wq_uin');
830
829
  const isLoginState =
831
830
  options?.loginColor?.dpin === 0 ? getWqAuthToken : getWqSkey && getWqUin;
832
831
  if (isLoginState) {
833
832
  this.info.loginState = true;
834
833
  resolve(true);
835
834
  } else {
836
835
  reject(false);
837
836
  }
838
837
  } else {
839
838
  Taro.request({
840
839
  url: api.isLogin,
841
840
  jsonp: true,
842
841
  timeout: 3000,
843
842
  success: (res) => {
844
843
  const { statusCode, data } = res;
845
844
  if (statusCode === 200 && data?.islogin && Number(data.islogin) === 1) {
846
845
  this.info.loginState = true;
847
846
  resolve(true);
848
847
  } else {
849
848
  reject(false);
850
849
  }
851
850
  },
852
851
  fail: (err) => {
853
852
  console.log('登录检查异常', err);
854
853
  reject(false);
855
854
  },
856
855
  });
857
856
  }
858
857
  });
859
858
  }
860
859
  }
861
860
 
862
861
  checkLoginStatus(options) {
863
862
  return new Promise(async (resolve, reject) => {
864
863
  try {
865
864
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
866
865
  if (getLoginState) {
867
866
  const { pin } = await this.getLoginCookie();
868
867
  this.info.userInfo = {
869
868
  pin,
870
869
  encodePin: encodeURIComponent(pin),
871
870
  ptkey: '',
872
871
  };
873
872
  resolve(true);
874
873
  } else {
875
874
  reject(false);
876
875
  }
877
876
  } catch (e) {
878
877
  reject(false);
879
878
  }
880
879
  });
881
880
  }
882
881
 
883
882
  updatePageAndLogInfo(updateQuery = {}) {
884
883
  const createUpdateQueryInfo: {
885
884
  query: {
886
885
  shopId?: string | number;
887
886
  venderId?: string | number;
888
887
  };
889
888
  updateShopInfoState: boolean;
890
889
  } = Object.assign(
891
890
  {},
892
891
  {
893
892
  query: {},
894
893
  updateShopInfoState: false,
895
894
  },
896
895
  updateQuery,
897
896
  );
898
897
  console.log(
899
898
  '获取当前下发的店铺查询参数',
900
899
  updateQuery,
901
900
  '获取之前保存的shopInfo店铺查询参数',
902
901
  this.info?.shopInfo,
903
902
  );
904
903
  const { query, updateShopInfoState } = createUpdateQueryInfo;
905
904
  const { shopId, venderId, un_area } = query;
906
905
  if (updateShopInfoState) {
907
906
  this.info.queryInfo = {
908
907
  ...this.info.queryInfo,
909
908
  ...query,
910
909
  };
911
910
  if (shopId && venderId) {
912
911
  this.info.shopInfo = {
913
912
  shopId: `${shopId}`,
914
913
  venderId: `${venderId}`,
915
914
  };
916
915
  }
917
916
  } else {
918
917
  this.info.queryInfo = {
919
918
  ...query,
920
919
  };
921
920
  if (
922
921
  this.info.shopInfo?.shopId &&
923
922
  this.info.shopInfo?.venderId &&
924
923
  (this.info.shopInfo.shopId == shopId || this.info.shopInfo.venderId == venderId)
925
924
  ) {
926
925
  this.info.queryInfo.shopId = this.info.shopInfo.shopId;
927
926
  this.info.queryInfo.venderId = this.info.shopInfo.venderId;
928
927
  console.log(
929
928
  '当前存储的店铺shopId和venderId与下发的店铺信息shopId或者venderId为同一个,补充shopId或者venderId查询参数',
930
929
  this.info.queryInfo,
931
930
  );
932
931
  }
933
932
  }
934
933
  this.info.queryInfo['shopId'] &&
935
934
  (this.info.queryInfo['shopId'] = `${this.info.queryInfo['shopId']}`);
936
935
  this.info.queryInfo['venderId'] &&
937
936
  (this.info.queryInfo['venderId'] = `${this.info.queryInfo['venderId']}`);
938
937
  console.log(
939
938
  'h5==获取店铺下发查询参数\n',
940
939
  query,
941
940
  '\n获取店铺最后查询参数\n',
942
941
  this.info.queryInfo,
943
942
  '\n是否为更新店铺状态\n',
944
943
  updateShopInfoState,
945
944
  );
946
945
  const changeArea = un_area && un_area.length > 0 ? un_area : ipLoc_djd ? ipLoc_djd : '';
947
946
  if (changeArea) {
948
947
  this.info.pageInfo.address = changeArea;
949
948
  this.info.pageInfo.un_area = changeArea;
950
949
  this.info.pageInfo.addressCommaStr = changeArea.replace(/_/g, ',');
951
950
  }
952
951
  }
953
952
 
954
953
  dealLoadSdkList() {
955
954
  const globalLoadJsList = window?.shopGlobalSwitch?.asyncLoadJsList ?? [];
956
955
  const businessLoadJsList = window?.PAGE_DATA?.businessData?.asyncLoadJsList ?? [];
957
956
  const concatLoadJsList = [].concat(globalLoadJsList, businessLoadJsList);
958
957
  let mergeLoadJsList = globalLoadJsList;
959
958
  try {
960
959
  mergeLoadJsList = concatLoadJsList.reduce((accArr: any[], current: any) => {
961
960
  const getFindIndex = accArr.findIndex((item) => item?.fileName === current?.fileName);
962
961
  getFindIndex !== -1
963
962
  ? (accArr[getFindIndex] = { ...accArr[getFindIndex], ...current })
964
963
  : accArr.push(current);
965
964
  return accArr;
966
965
  }, []);
967
966
  } catch (e) {
968
967
  console.log('LoadJsList合并错误', e);
969
968
  }
970
969
  console.log(
971
970
  'globalLoadJsList',
972
971
  globalLoadJsList,
973
972
  'businessLoadJsList',
974
973
  businessLoadJsList,
975
974
  '两个加载jsList集合合并完成',
976
975
  mergeLoadJsList,
977
976
  );
978
977
  this.loadJsSdkList = mergeLoadJsList;
979
978
  return this.loadJsSdkList;
980
979
  }
981
980
 
982
981
  renderNextTickLoadSdk() {
983
982
  Taro.nextTick(() => {
984
983
  console.log(
985
984
  '页面渲染的下一帧执行的js加载方法,当前nextTick存在state的渲染问题,先延迟1s=======',
986
985
  );
987
986
  setTimeout(() => {
988
987
  this.loadOtherSdk(LoadJsInitTriggerType.NRXT_TICK, this.loadJsSdkList);
989
988
  }, 1000);
990
989
  });
991
990
  }
992
991
 
993
992
  loadOtherSdk(triggerType = LoadJsInitTriggerType.NOW, loadJsList: any[] = []) {
994
993
  const getLoadJsList =
995
994
  Array.isArray(loadJsList) && loadJsList.length > 0 ? loadJsList : this.dealLoadSdkList();
996
995
  const getLoadFilterList = getLoadJsList.filter((item) => {
997
996
  const getInitLoadEnvType = item?.initLoadEnvType || LoadJsInitLoadEnvType.ALL;
998
997
  let getLoastLoadEventState = true;
999
998
  if (getInitLoadEnvType === LoadJsInitLoadEnvType.JD_APP) {
1000
999
  getLoastLoadEventState = isJdApp;
1001
1000
  }
1002
1001
  else if (getInitLoadEnvType === LoadJsInitLoadEnvType.M) {
1003
1002
  getLoastLoadEventState = !isJdApp || !!isJdAndHarmonyDevice;
1004
1003
  }
1005
1004
  const getInitTriggerType =
1006
1005
  isJdApp && item?.initJdAppTriggerType
1007
1006
  ? item?.initTriggerType
1008
1007
  : item?.initTriggerType || LoadJsInitTriggerType.NOW;
1009
1008
  const getInitLinkTriggerWay = window?.PAGE_DATA[item?.initLinkTriggerWay] || false;
1010
1009
  return getLoastLoadEventState && getInitTriggerType === triggerType && getInitLinkTriggerWay;
1011
1010
  });
1012
1011
  console.log(
1013
1012
  '获取当前触发方式',
1014
1013
  triggerType,
1015
1014
  '获取当前最后加载的js集合',
1016
1015
  getLoadFilterList,
1017
1016
  '过滤前的加载集合',
1018
1017
  getLoadJsList,
1019
1018
  );
1020
1019
  getLoadFilterList.length > 0 &&
1021
1020
  getLoadFilterList.forEach((item) => {
1022
1021
  const isLoadState = /sgm/.test(item?.fileName)
1023
1022
  ? window?.shopGlobalSwitch?.openSgm === 'true'
1024
1023
  : true;
1025
1024
  isLoadState &&
1026
1025
  this.loadItemSdkPromise(item)
1027
1026
  .then((res) => {
1028
1027
  console.info('当前js地址' + item?.src, '加载状态', res);
1029
1028
  const isFileNameNewDraSdkJs = res?.fileName === 'newDraSdkJs';
1030
1029
  if (isFileNameNewDraSdkJs && window?.dra?.run) {
1031
1030
  window.dra.run('init', { aid: res?.aid });
1032
1031
  window.dra.run('start');
1033
1032
  }
1034
1033
  })
1035
1034
  .catch((err) => {
1036
1035
  console.info('当前js地址加载异常', item?.src);
1037
1036
  window?.fetchErrorData &&
1038
1037
  window.fetchErrorData({
1039
1038
  title: '公共js加载异常',
1040
1039
  type: 'jsLoad',
1041
1040
  data: err,
1042
1041
  });
1043
1042
  });
1044
1043
  });
1045
1044
  }
1046
1045
  loadScriptEle(jsInfo, resolve, reject) {
1047
1046
  const getFileName = jsInfo?.fileName;
1048
1047
  if (getFileName) {
1049
1048
  const getEleId = `J_loadJs_${getFileName}`;
1050
1049
  const getEle = document.getElementById(getEleId);
1051
1050
  if (!getEle) {
1052
1051
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
1053
1052
  const _sgmEle = document.createElement('script');
1054
1053
  _sgmEle.id = getEleId;
1055
1054
  _sgmEle.onload = function () {
1056
1055
  resolve({
1057
1056
  ...jsInfo,
1058
1057
  jsTip: 'js加载成功',
1059
1058
  });
1060
1059
  };
1061
1060
  _sgmEle.onerror = function () {
1062
1061
  reject({
1063
1062
  ...jsInfo,
1064
1063
  env: getSgmCustomCode(jsLoadErrorSgmCode),
1065
1064
  jsReqError: '当前js创建标签触发onerror异常回调,请排查网络络错误或语法错误或运行时错误',
1066
1065
  });
1067
1066
  };
1068
1067
  const dataAttrList = ['timeout', 'fileName', 'env'];
1069
1068
  const getJsInfoKeyList = Object.keys(jsInfo);
1070
1069
  getJsInfoKeyList.forEach((key) => {
1071
1070
  if (key === 'async') {
1072
1071
  _sgmEle.async = jsInfo[key];
1073
1072
  } else if (key === 'crossOrigin') {
1074
1073
  _sgmEle.crossOrigin = jsInfo[key];
1075
1074
  } else if (key === 'src') {
1076
1075
  _sgmEle.src = `${jsInfo[key]}`;
1077
1076
  } else if (dataAttrList.includes(key) || /init/.test(key)) {
1078
1077
  _sgmEle.setAttribute(`data-${key}`, jsInfo[key]);
1079
1078
  } else {
1080
1079
  _sgmEle.setAttribute(key, jsInfo[key]);
1081
1080
  }
1082
1081
  });
1083
1082
  document.head.appendChild(_sgmEle);
1084
1083
  } else {
1085
1084
  console.log(`当前${jsInfo?.fileName || 'js'}已经存在页面中,可以直接调用相关方法`, jsInfo);
1086
1085
  resolve({
1087
1086
  ...jsInfo,
1088
1087
  jsTip: 'js本身已存在页面中',
1089
1088
  });
1090
1089
  }
1091
1090
  } else {
1092
1091
  console.warn('当前js资源信息缺少必要的参数fileName,请关注', jsInfo);
1093
1092
  }
1094
1093
  }
1095
1094
 
1096
1095
  loadItemSdkPromise(jsInfo = {}) {
1097
1096
  if (jsInfo?.src) {
1098
1097
  const getInitLoadType =
1099
1098
  isJdApp && jsInfo?.initJdAppLoadType
1100
1099
  ? jsInfo?.initJdAppLoadType
1101
1100
  : jsInfo?.initLoadType || LoadJsInitLoadType.ALL;
1102
1101
  if (getInitLoadType !== LoadJsInitLoadType.NONE) {
1103
1102
  const getFileKeyName = jsInfo?.fileName || jsInfo?.src;
1104
1103
  if (!this.loadJsSdkListCachePromise[getFileKeyName]) {
1105
1104
  if (getInitLoadType !== LoadJsInitLoadType.INSERT_ELE) {
1106
1105
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
1107
1106
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
1108
1107
  try {
1109
1108
  const jsXhrRequest = new XMLHttpRequest();
1110
1109
  jsXhrRequest.timeout = jsInfo?.timeout ?? 2000;
1111
1110
  const jsUrl = `${jsInfo?.src}`;
1112
1111
  jsXhrRequest.open('GET', jsUrl, true);
1113
1112
  jsXhrRequest.onreadystatechange = () => {
1114
1113
  if (jsXhrRequest.readyState === 4) {
1115
1114
  const getReqStatus = jsXhrRequest.status;
1116
1115
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
1117
1116
  const getInsetHeadState = getInitLoadType === LoadJsInitLoadType.ALL;
1118
1117
  if (getInsetHeadState) {
1119
1118
  this.loadScriptEle(jsInfo, resolve, reject);
1120
1119
  } else {
1121
1120
  resolve({
1122
1121
  ...jsInfo,
1123
1122
  jsTip: 'js请求成功,暂未插入head节点,业务自行单独插入',
1124
1123
  });
1125
1124
  }
1126
1125
  getReqStatus !== 200 &&
1127
1126
  sgmCustomReport({
1128
1127
  type: 3,
1129
1128
  code: 'js_load_special_code',
1130
1129
  msg: {
1131
1130
  msg: '当前js加载成功,状态非200,特殊上报观察',
1132
1131
  jsReqState: getReqStatus,
1133
1132
  env: getSgmCustomCode('js_load_special_code'),
1134
1133
  data: jsInfo,
1135
1134
  },
1136
1135
  });
1137
1136
  } else {
1138
1137
  const getRes = {
1139
1138
  ...jsInfo,
1140
1139
  env: getSgmCustomCode(jsLoadErrorSgmCode),
1141
1140
  jsReqError: `请求状态异常,状态码为${getReqStatus}`,
1142
1141
  jsReqState: getReqStatus,
1143
1142
  };
1144
1143
  console.log('当前js请求状态异常,具体信息见', getRes);
1145
1144
  reject(getRes);
1146
1145
  }
1147
1146
  }
1148
1147
  };
1149
1148
  jsXhrRequest.onerror = () => {
1150
1149
  const getRes = {
1151
1150
  ...jsInfo,
1152
1151
  env: getSgmCustomCode(jsLoadErrorSgmCode),
1153
1152
  jsReqError: '请求错误',
1154
1153
  };
1155
1154
  console.log('当前js请求错误', getRes);
1156
1155
  jsXhrRequest.abort();
1157
1156
  reject(getRes);
1158
1157
  };
1159
1158
  jsXhrRequest.ontimeout = () => {
1160
1159
  const getRes = {
1161
1160
  ...jsInfo,
1162
1161
  env: getSgmCustomCode(jsLoadErrorSgmCode),
1163
1162
  jsReqError: `请求${jsXhrRequest.timeout}ms超时异常`,
1164
1163
  jsReqState: jsXhrRequest.status,
1165
1164
  };
1166
1165
  console.log('当前js请求超时异常', getRes);
1167
1166
  jsXhrRequest.abort();
1168
1167
  reject(getRes);
1169
1168
  };
1170
1169
  jsXhrRequest.send();
1171
1170
  } catch (e) {
1172
1171
  console.log('执行js请求异常', e);
1173
1172
  reject({
1174
1173
  ...jsInfo,
1175
1174
  env: getSgmCustomCode(jsLoadErrorSgmCode),
1176
1175
  jsReqError: '未知异常',
1177
1176
  error: e,
1178
1177
  });
1179
1178
  }
1180
1179
  });
1181
1180
  } else {
1182
1181
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
1183
1182
  return this.loadScriptEle(jsInfo, resolve, reject);
1184
1183
  });
1185
1184
  }
1186
1185
  }
1187
1186
  return this.loadJsSdkListCachePromise[getFileKeyName];
1188
1187
  } else {
1189
1188
  return Promise.resolve({
1190
1189
  ...jsInfo,
1191
1190
  jsTip: 'js加载方式设置为不加载,当前不做处理',
1192
1191
  });
1193
1192
  }
1194
1193
  } else {
1195
1194
  return Promise.reject(jsInfo);
1196
1195
  }
1197
1196
  }
1197
+ import Taro from '@tarojs/taro';
1198
1198
  isIosDevice,
1199
1199
  isAndroidDevice,
1200
1200
  isJdAndHarmonyDevice,
1201
1201
  isJdAndAndroidDevice,
1202
1202
  jdAppVersion,
1203
1203
  jdAppVersionStr,
1204
1204
  isString,
1205
1205
  isObject,
1206
1206
  serialize,
1207
1207
  dealNativePixelToCssPixel,
1208
1208
  isPc,
1209
1209
  BUSINESS_TYPE,
1210
1210
  SECTION_HOME_TAB_NAME_TYPE,
1211
1211
  SECTION_HOME_TAB_TYPE,
1212
1212
  WXAPP_BIZ_KEY,
1213
1213
  WX_BUSINESS_TYPE,
1214
1214
  MPAAS_CONFIG_APP_VERSION,
1215
1215
  MPAAS_CONFIG_APP_LOW_VERSION,
1216
1216
  WXAPP_BIZ_SHOP_LIGHT_KEY,
1217
1217
  LoadJsInitLoadEnvType,
1218
1218
  LoadJsInitLoadType,
1219
1219
  LoadJsInitTriggerType,
1220
1220
  TaroEventType,
1221
1221
  getSystemInfos,
1222
1222
  ipLoc_djd,
1223
1223
  sgmCustomReport,
1224
1224
  getTaroStorageKeyValue,
1225
1225
  setTaroStorage,
1226
1226
  const designWidth = 750;
1227
1227
  return (
1228
1228
  Math.ceil((((parseInt(String(size), 10) / 40) * 750) / designWidth) * 10000) / 10000 + 'rem'
1229
1229
  );
1230
1230
  abTestLabels: {},
1231
1231
  loginState: false,
1232
1232
  cookiesStr: '',
1233
1233
  userInfo: userPinKey,
1234
1234
  isJingGouMiniViewState: false,
1235
1235
  isJingxiMiniViewState: false,
1236
1236
  pageInfo: {
1237
1237
  wxBusinessType: WX_BUSINESS_TYPE.NO,
1238
1238
  address: '',
1239
1239
  addressCommaStr: '',
1240
1240
  un_area: '',
1241
1241
  vapptype: '1',
1242
1242
  pageType: 'home',
1243
1243
  isExposureState: false,
1244
1244
  moduleId: '',
1245
1245
  entrance: '',
1246
1246
  dataType: BUSINESS_TYPE.ONLINE,
1247
1247
  floorExposureInfo: {},
1248
1248
  floorVideInfo: {},
1249
1249
  productVideInfo: {},
1250
1250
  tabsLoadAllDataInfo: {
1251
1251
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: false,
1252
1252
  },
1253
1253
  updateShopInfosAllState: false,
1254
1254
  isVipShop: false,
1255
1255
  isJdShowNativeImmersivePlayer: false,
1256
1256
  ...shopConfig,
1257
1257
  pageScrollTop: 0,
1258
1258
  pageIdxHeightInfo: {
1259
1259
  list: [],
1260
1260
  },
1261
1261
  shopNavBarHeight: 0,
1262
1262
  },
1263
1263
  defaultQueryLogInfo: {
1264
1264
  sourceType: 'JDshop',
1265
1265
  sourceValue: '',
1266
1266
  moduleId: 'none',
1267
1267
  entrance: 'none',
1268
1268
  },
1269
1269
  sysInfo: {
1270
1270
  windowWidth: isPc ? 375 : 0,
1271
1271
  containerWidth: isPc ? 375 : 0,
1272
1272
  windowHeight: 0,
1273
1273
  netWorkType: '4g',
1274
1274
  jdBottomBarHeight: 0,
1275
1275
  jdNativeHeaderHeight: 0,
1276
1276
  isJdTabletDevice: false,
1277
1277
  isJdTabletLandscape: false,
1278
1278
  },
1279
1279
  queryInfo: {},
1280
1280
  shopInfo: {},
1281
1281
  openAppData: {},
1282
1282
  public info: CommonInterFace.BaseConfigInfo;
1283
1283
  public config: {
1284
1284
  [key: string]: any;
1285
1285
  };
1286
1286
  public lazyContainer: CommonInterFace.lazyContainer;
1287
1287
  public renderedIsvComponents: CommonInterFace.renderedIsvComponents;
1288
1288
  public rootEleNode: HTMLElement | null;
1289
1289
  public checkStatusAndLoginPromise: object | null;
1290
1290
  private jmfeRegisterStatePromise: Promise<any> | null;
1291
1291
  private jmfeRegisterState: boolean;
1292
1292
  public loadJsSdkList: Array<any>;
1293
1293
  public loadJsSdkListCachePromise: any;
1294
1294
  constructor(opt) {
1295
1295
  this.info = this._getConfig(opt);
1296
1296
  this.config = {};
1297
1297
  this.loadJsSdkList = [];
1298
1298
  this.loadJsSdkListCachePromise = {};
1299
1299
  this.lazyContainer = {
1300
1300
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: {
1301
1301
  appLazyContainerList: [],
1302
1302
  appLazyFinishContainerList: [],
1303
1303
  },
1304
1304
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_PROMOTION]]: {
1305
1305
  appLazyContainerList: [],
1306
1306
  appLazyFinishContainerList: [],
1307
1307
  },
1308
1308
  };
1309
1309
  this.renderedIsvComponents = {};
1310
1310
  this.rootEleNode = document.querySelector('body');
1311
1311
  this.checkStatusAndLoginPromise = null;
1312
1312
  this.jmfeRegisterStatePromise = null;
1313
1313
  this.loadOtherSdk();
1314
1314
  isJdApp && this.jmfeReayPromise();
1315
1315
  }
1316
1316
  _getConfig(opt) {
1317
1317
  return Object.assign({}, DefaultConfig, opt);
1318
1318
  }
1319
1319
 
1320
1320
  jmfeReayPromise(): Promise<any> {
1321
1321
  if (isJdApp) {
1322
1322
  if (this.jmfeRegisterState) {
1323
1323
  return Promise.resolve(true);
1324
1324
  } else {
1325
1325
  !this.jmfeRegisterStatePromise &&
1326
1326
  (this.jmfeRegisterStatePromise = new Promise((resolve, reject) => {
1327
1327
  ready('jmfe', 3000)
1328
1328
  .then(() => {
1329
1329
  window?.jmfe && window.jmfe.registerCode(JSSDK_APP_WEBVIEW_CODE);
1330
1330
  this.jmfeRegisterState = true;
1331
1331
  resolve(true);
1332
1332
  console.log('松果app内初始化注册jmfe认证完成');
1333
1333
  })
1334
1334
  .catch(() => {
1335
1335
  reject(false);
1336
1336
  });
1337
1337
  }));
1338
1338
  return this.jmfeRegisterStatePromise;
1339
1339
  }
1340
1340
  } else {
1341
1341
  return Promise.reject(false);
1342
1342
  }
1343
1343
  }
1344
1344
 
1345
1345
  getJdScreenSizeInfo() {
1346
1346
  return new Promise((resolve) => {
1347
1347
  this.jmfeReayPromise().then(() => {
1348
1348
  return Promise.race([
1349
1349
  window.jmfe.getScreenSize(),
1350
1350
  this.taskTimeoutPromise(() => {
1351
1351
  return {
1352
1352
  status: '-10',
1353
1353
  msg: '获取大屏信息2s超时',
1354
1354
  };
1355
1355
  }),
1356
1356
  ])
1357
1357
  .then((res) => {
1358
1358
  console.log('===获取app大屏信息====', res);
1359
1359
  const { status, data } = res;
1360
1360
  if (status === '0' && data) {
1361
1361
  const { sizeType, isLandscape, pageHeight, pageWidth } = data;
1362
1362
  const getPageInfo = dealNativePixelToCssPixel({
1363
1363
  pageWidth,
1364
1364
  pageHeight,
1365
1365
  });
1366
1366
  this.info.sysInfo.jdScreenSizeType = sizeType;
1367
1367
  this.info.sysInfo.isJdTabletDevice = window.screen?.width >= 720;
1368
1368
  this.info.sysInfo.isJdTabletLandscape = isLandscape === '1';
1369
1369
  console.log(
1370
1370
  '===计算是否是app大屏信息,需满足宽度最新720===',
1371
1371
  getPageInfo,
1372
1372
  '原始数据',
1373
1373
  data,
1374
1374
  );
1375
1375
  resolve(getPageInfo);
1376
1376
  } else {
1377
1377
  resolve(false);
1378
1378
  }
1379
1379
  })
1380
1380
  .catch((err) => {
1381
1381
  console.log('获取大屏信息异常', err);
1382
1382
  resolve(false);
1383
1383
  });
1384
1384
  });
1385
1385
  });
1386
1386
  }
1387
1387
 
1388
1388
  listenJdTabletScreenChange() {
1389
1389
  this.jmfeReayPromise().then(() => {
1390
1390
  try {
1391
1391
  console.log('初始化监听大屏信息变化', window.jmfe.listenDeviceScreenChange);
1392
1392
  window.jmfe.listenDeviceScreenChange((event) => {
1393
1393
  console.log(
1394
1394
  '监听app大屏信息变化,orientation为landscape表示横屏,multiScreen为1表示android端分屏',
1395
1395
  event,
1396
1396
  '通过前端判断是不是横屏',
1397
1397
  window.matchMedia('(orientation: landscape)')?.matches,
1398
1398
  );
1399
1399
  const { orientation } = event?.data;
1400
1400
  if (orientation) {
1401
1401
  this.info.sysInfo.isJdTabletLandscape = orientation === 'landscape';
1402
1402
  Taro.eventCenter.trigger(
1403
1403
  TaroEventType.TABLE_SCREEN_CHANGE,
1404
1404
  this.info.sysInfo.isJdTabletLandscape,
1405
1405
  orientation,
1406
1406
  );
1407
1407
  }
1408
1408
  });
1409
1409
  } catch (error) {
1410
1410
  console.log('listenScreenChange的打印error:', error);
1411
1411
  }
1412
1412
  });
1413
1413
  }
1414
1414
 
1415
1415
  updateBusinessDomainAndApi(domain, api) {
1416
1416
  }
1417
1417
 
1418
1418
  formatNativeScreenPageData(action) {
1419
1419
  let getChangePageInfo: any = null;
1420
1420
  try {
1421
1421
  const getNativeScreenPageInfoStr = window.XWebView?._callNative(
1422
1422
  JSON.stringify({
1423
1423
  plugin: 'JDHybridScreenPlugin',
1424
1424
  action,
1425
1425
  sync: '1',
1426
1426
  }),
1427
1427
  );
1428
1428
  const getChangePageInfoData =
1429
1429
  typeof getNativeScreenPageInfoStr === 'string'
1430
1430
  ? JSON.parse(getNativeScreenPageInfoStr)
1431
1431
  : null;
1432
1432
  if (getChangePageInfoData && typeof getChangePageInfoData === 'object') {
1433
1433
  const { code, data } = getChangePageInfoData;
1434
1434
  getChangePageInfo = code && code === '0' ? data : null;
1435
1435
  }
1436
1436
  } catch (e) {
1437
1437
  console.log('JDHybridScreenPlugin转换异常', e);
1438
1438
  }
1439
1439
  return getChangePageInfo;
1440
1440
  }
1441
1441
 
1442
1442
  isAndroidFoldScreen() {
1443
1443
  return this.formatNativeScreenPageData('isFoldScreen') === '1';
1444
1444
  }
1445
1445
 
1446
1446
  getJdAndroidPageChangeScreenInfo() {
1447
1447
  const getPageScreenInfo = this.formatNativeScreenPageData('getScreenSize');
1448
1448
  if (getPageScreenInfo && getPageScreenInfo?.pageWidth && getPageScreenInfo?.pageHeight) {
1449
1449
  const { pageWidth, pageHeight } = dealNativePixelToCssPixel({
1450
1450
  pageWidth: getPageScreenInfo.pageWidth,
1451
1451
  pageHeight: getPageScreenInfo.pageHeight,
1452
1452
  });
1453
1453
  getPageScreenInfo.pageWidth = pageWidth;
1454
1454
  getPageScreenInfo.pageHeight = pageHeight;
1455
1455
  }
1456
1456
  return getPageScreenInfo;
1457
1457
  }
1458
1458
 
1459
1459
  async getSystemInfo(params) {
1460
1460
  let info: UtilsInterFace.taroGetSystemInfoSyncRes | any = getSystemInfos(params);
1461
1461
  if (isJdAndAndroidDevice && info?.initWindowWidth <= 0) {
1462
1462
  let _isfoldScreen = false;
1463
1463
  const getStorageData = getTaroStorageKeyValue('jd_shopx_androidIsFoldScreen');
1464
1464
  console.info(
1465
1465
  '获取当前本地存储是否有jd_shopx_androidIsFoldScreen',
1466
1466
  getStorageData,
1467
1467
  '通过缓存值第一次判断是否是折叠屏',
1468
1468
  getStorageData === 'true',
1469
1469
  );
1470
1470
  if (!getStorageData) {
1471
1471
  _isfoldScreen = this.isAndroidFoldScreen();
1472
1472
  setTaroStorage('jd_shopx_androidIsFoldScreen', `${_isfoldScreen}`);
1473
1473
  } else {
1474
1474
  _isfoldScreen = getStorageData === 'true';
1475
1475
  }
1476
1476
  if (_isfoldScreen) {
1477
1477
  const getJdAndroidPageInfo = this.getJdAndroidPageChangeScreenInfo();
1478
1478
  if (getJdAndroidPageInfo) {
1479
1479
  info = getSystemInfos(getJdAndroidPageInfo);
1480
1480
  console.warn(
1481
1481
  '当前为松果安卓折叠屏app,获取折叠屏信息',
1482
1482
  getJdAndroidPageInfo,
1483
1483
  '获取转换后的系统信息',
1484
1484
  info,
1485
1485
  );
1486
1486
  sgmCustomReport({
1487
1487
  type: 2,
1488
1488
  code: 'android_jdapp_foldScreen_info',
1489
1489
  msg: {
1490
1490
  title: `松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异`,
1491
1491
  androidPageInfo: getJdAndroidPageInfo,
1492
1492
  jdAppVersionStr,
1493
1493
  taroSysInfo: info,
1494
1494
  },
1495
1495
  });
1496
1496
  }
1497
1497
  }
1498
1498
  }
1499
1499
  if (isJdApp) {
1500
1500
  info?.isJdTabletDevice && this.listenJdTabletScreenChange();
1501
1501
  }
1502
1502
  this.info.sysInfo = {
1503
1503
  actualNavBarHeight: 0,
1504
1504
  ...this.info.sysInfo,
1505
1505
  ...info,
1506
1506
  safeContentHeight: info?.screenHeight,
1507
1507
  headerHeight: 0,
1508
1508
  tabBarHeight: 0,
1509
1509
  };
1510
1510
  if (isJdApp) {
1511
1511
  this.info.sysInfo['hostVersionName'] = jdAppVersionStr;
1512
1512
  this.info.sysInfo['hostAppVersion'] = jdAppVersion;
1513
1513
  this.getAddressCachePromise();
1514
1514
  this.getElderModePromise();
1515
1515
  this.getJDAppearanceStatePromise();
1516
1516
  this.createJdAndroidRquestEventForTouchStart();
1517
1517
  }
1518
1518
  this.getWifiVideoAutoPlayAsync();
1519
1519
  this.getMPaasConfigAsync();
1520
1520
  this.getNetWorkType();
1521
1521
  }
1522
1522
 
1523
1523
  taskTimeoutPromise(callBack, timeout = 2000) {
1524
1524
  return new Promise((resolve) => {
1525
1525
  setTimeout(() => {
1526
1526
  const getCallBackRes = typeof callBack === 'function' && callBack();
1527
1527
  return resolve(getCallBackRes || false);
1528
1528
  }, timeout);
1529
1529
  });
1530
1530
  }
1531
1531
 
1532
1532
  getElderModePromise() {
1533
1533
  if (this.info.sysInfo.hasOwnProperty('jdAppModeType')) {
1534
1534
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
1535
1535
  } else {
1536
1536
  if (isJdAndAndroidDevice) {
1537
1537
  this.info.sysInfo.jdAppModeType = '0';
1538
1538
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
1539
1539
  } else {
1540
1540
  return Promise.race([
1541
1541
  this.taskTimeoutPromise(() => {
1542
1542
  this.info.sysInfo.jdAppModeType = '0';
1543
1543
  return this.info.sysInfo.jdAppModeType;
1544
1544
  }),
1545
1545
  new Promise((resolve) => {
1546
1546
  const getCallBackName = `getJdCurrentModeType${Date.now()}`;
1547
1547
  if (!window[getCallBackName]) {
1548
1548
  window[getCallBackName] = (res) => {
1549
1549
  try {
1550
1550
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
1551
1551
  const { status, data, msg } = getResJson;
1552
1552
  console.log(`获取松果app展示模式成功,返回结果${data}`);
1553
1553
  if (status === '0') {
1554
1554
  this.info.sysInfo.jdAppModeType = data;
1555
1555
  resolve(data);
1556
1556
  } else {
1557
1557
  resolve('0');
1558
1558
  }
1559
1559
  } catch (e) {
1560
1560
  resolve('0');
1561
1561
  }
1562
1562
  window[getCallBackName] = null;
1563
1563
  };
1564
1564
  }
1565
1565
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
1566
1566
  method: 'callSyncRouterModuleWithParams',
1567
1567
  params: JSON.stringify({
1568
1568
  routerURL: 'router://JDBModeModule/getCurrentMode',
1569
1569
  routerParam: {},
1570
1570
  callBackName: `window.${getCallBackName}`,
1571
1571
  callBackId: `${getCallBackName}Ios`,
1572
1572
  }),
1573
1573
  });
1574
1574
  }),
1575
1575
  ]);
1576
1576
  }
1577
1577
  }
1578
1578
  }
1579
1579
  getAPPUseStraightCorner() {
1580
1580
  const routerURL = 'router://JDBaseUtilsModule/isUI14Enable';
1581
1581
  const params = {
1582
1582
  routerURL,
1583
1583
  routerParam: {},
1584
1584
  jdRouter: '1',
1585
1585
  };
1586
1586
  if (this.info.sysInfo.hasOwnProperty('jdStraightCorner')) {
1587
1587
  return Promise.resolve(this.info.sysInfo.jdStraightCorner);
1588
1588
  } else {
1589
1589
  return this.jmfeReayPromise()
1590
1590
  .then(() => {
1591
1591
  if (isJdAndHarmonyDevice || !isJdApp) {
1592
1592
  console.log('not APP or is Harmony');
1593
1593
  return Promise.resolve(false);
1594
1594
  }
1595
1595
  console.log('jmfe setShareInfo', params);
1596
1596
  return Promise.race([
1597
1597
  window.jmfe.callRouter(params),
1598
1598
  this.taskTimeoutPromise(() => {
1599
1599
  return false;
1600
1600
  }),
1601
1601
  ]).then(({ status, data }) => {
1602
1602
  console.log('004 ~ file: index.tsx:133 ~ .then ~ data:', data);
1603
1603
  console.log('004 ~ file: index.tsx:133 ~ .then ~ status:', status);
1604
1604
  this.info.sysInfo.jdStraightCorner = status === '0' && Number(data) === 1;
1605
1605
  return Promise.resolve(status === '0' && Number(data) === 1);
1606
1606
  });
1607
1607
  })
1608
1608
  .catch((e) => {
1609
1609
  console.log('jmfe error', e);
1610
1610
  return Promise.resolve(false);
1611
1611
  });
1612
1612
  }
1613
1613
  }
1614
1614
 
1615
1615
  getJDAppearanceStatePromise() {
1616
1616
  if (this.info.sysInfo.hasOwnProperty('jdAppearanceState')) {
1617
1617
  return Promise.resolve(this.info.sysInfo.jdAppearanceState);
1618
1618
  } else {
1619
1619
  return Promise.race([
1620
1620
  this.taskTimeoutPromise(() => {
1621
1621
  this.info.sysInfo.jdAppearanceState = '0';
1622
1622
  return this.info.sysInfo.jdAppearanceState;
1623
1623
  }),
1624
1624
  new Promise((resolve) => {
1625
1625
  const getCallBackName = `getJdCurrentAppearanceState${Date.now()}`;
1626
1626
  if (!window[getCallBackName]) {
1627
1627
  window[getCallBackName] = (res) => {
1628
1628
  try {
1629
1629
  console.log('getJDAppearanceStatePromise', res);
1630
1630
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
1631
1631
  const { status, data, msg } = getResJson;
1632
1632
  console.log(`获取松果app是否开启黑暗模式成功,返回结果${data}`);
1633
1633
  if (status === '0') {
1634
1634
  this.info.sysInfo.jdAppearanceState = data;
1635
1635
  resolve(data);
1636
1636
  } else {
1637
1637
  resolve('0');
1638
1638
  }
1639
1639
  } catch (e) {
1640
1640
  resolve('0');
1641
1641
  }
1642
1642
  window[getCallBackName] = null;
1643
1643
  };
1644
1644
  }
1645
1645
  if (isAndroidDevice) {
1646
1646
  const jsonString = JSON.stringify({
1647
1647
  callBackName: `window.${getCallBackName}`,
1648
1648
  });
1649
1649
  console.log('window.JDAppearance', window?.JDAppearance);
1650
1650
  window?.JDAppearance &&
1651
1651
  window?.JDAppearance?.getUiState &&
1652
1652
  window.JDAppearance.getUiState(jsonString);
1653
1653
  } else {
1654
1654
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
1655
1655
  method: 'callSyncRouterModuleWithParams',
1656
1656
  params: JSON.stringify({
1657
1657
  routerURL: 'router://JDWebViewBusinessModule/getJDAppearanceState',
1658
1658
  routerParam: {},
1659
1659
  callBackName: `window.${getCallBackName}`,
1660
1660
  callBackId: `${getCallBackName}Ios`,
1661
1661
  }),
1662
1662
  });
1663
1663
  }
1664
1664
  }),
1665
1665
  ]);
1666
1666
  }
1667
1667
  }
1668
1668
 
1669
1669
  createJdAndroidRquestEventForTouchStart() {
1670
1670
  if (isJdAndAndroidDevice && window?.JdAndroid) {
1671
1671
  const rootEleNode = document.querySelector('body');
1672
1672
  if (rootEleNode) {
1673
1673
  rootEleNode.addEventListener('touchstart', this.jdAndroidAddEventListenerTouchStart, false);
1674
1674
  }
1675
1675
  }
1676
1676
  }
1677
1677
  jdAndroidAddEventListenerTouchStart(e) {
1678
1678
  const isH5SwiperCustomEle = e?.target?.closest('.J_h5SwiperCustom');
1679
1679
  if (!isH5SwiperCustomEle && window?.JdAndroid) {
1680
1680
  const hasCustomEle = e
1681
1681
  ? e?.target?.closest('.J_customScroll') || e?.target?.closest('.J_customLayout')
1682
1682
  : false;
1683
1683
  if (!hasCustomEle) {
1684
1684
  window?.JdAndroid?.requestEvent && window.JdAndroid.requestEvent(false);
1685
1685
  console.log(
1686
1686
  'createJdAndroidRquestEvent 所有松果安卓APP内的document touch start事件执行检测requestEvent并重置为false',
1687
1687
  );
1688
1688
  }
1689
1689
  }
1690
1690
  }
1691
1691
  removeJdAndroidRquestEventForTouchStart() {
1692
1692
  if (isJdAndAndroidDevice && window.JdAndroid) {
1693
1693
  const rootEleNode = document.querySelector('body');
1694
1694
  if (rootEleNode) {
1695
1695
  rootEleNode.removeEventListener(
1696
1696
  'touchstart',
1697
1697
  this.jdAndroidAddEventListenerTouchStart,
1698
1698
  false,
1699
1699
  );
1700
1700
  }
1701
1701
  }
1702
1702
  }
1703
1703
 
1704
1704
  getNetWorkType() {
1705
1705
  if (isJdApp) {
1706
1706
  this.jmfeReayPromise().then(() => {
1707
1707
  window.jmfe
1708
1708
  .getNetworkStatus()
1709
1709
  .then(({ status, data }) => {
1710
1710
  console.log('在app内初始化通过jmfe对象获取网络状态完成,当前网络状态====', data);
1711
1711
  if (status === '0') {
1712
1712
  this.info.sysInfo['netWorkType'] = data;
1713
1713
  } else {
1714
1714
  this._taroGetNetworkType();
1715
1715
  }
1716
1716
  })
1717
1717
  .catch((err) => {
1718
1718
  console.log('在app内初始化通过jmfe对象获取网络状态异常====', err);
1719
1719
  this._taroGetNetworkType();
1720
1720
  });
1721
1721
  });
1722
1722
  } else {
1723
1723
  this._taroGetNetworkType();
1724
1724
  }
1725
1725
  }
1726
1726
  _taroGetNetworkType() {
1727
1727
  Taro.getNetworkType().then((getRes) => {
1728
1728
  if (getRes && getRes.networkType) {
1729
1729
  this.info.sysInfo['netWorkType'] = getRes.networkType;
1730
1730
  console.log(
1731
1731
  '在app内通过taro对象获取网络状态完成,当前网络状态',
1732
1732
  this.info.sysInfo['netWorkType'],
1733
1733
  );
1734
1734
  }
1735
1735
  });
1736
1736
  }
1737
1737
 
1738
1738
  getCacheAddressRouter() {
1739
1739
  if (window.jmfe && isJdApp) {
1740
1740
  if (!isJdAndHarmonyDevice) {
1741
1741
  return Promise.race([
1742
1742
  window.jmfe.callRouter({
1743
1743
  jdRouter: '1',
1744
1744
  routerURL: isAndroidDevice
1745
1745
  ? 'router://JDAddressModule/getCacheAddress'
1746
1746
  : 'router://JDBAddressCacheManagerModule/getCacheAddress',
1747
1747
  routerParam: { sceneId: 'basicShoppingProcess' },
1748
1748
  }),
1749
1749
  this.taskTimeoutPromise(() => {
1750
1750
  return {
1751
1751
  status: '-1000',
1752
1752
  msg: '原生router协议获取地址信息超时',
1753
1753
  };
1754
1754
  }, 3000),
1755
1755
  ]);
1756
1756
  } else {
1757
1757
  return Promise.resolve({
1758
1758
  status: '-1001',
1759
1759
  msg: '鸿蒙系统调用jmfe异常,获取失败',
1760
1760
  });
1761
1761
  }
1762
1762
  } else {
1763
1763
  return Promise.resolve({
1764
1764
  status: '-1002',
1765
1765
  msg: 'jmfe不存在,获取失败',
1766
1766
  });
1767
1767
  }
1768
1768
  }
1769
1769
 
1770
1770
  getAddressCachePromise() {
1771
1771
  return new Promise((resolve) => {
1772
1772
  if (this?.info?.sysInfo?.lat && this?.info?.sysInfo?.lng && this?.info?.sysInfo?.area) {
1773
1773
  resolve({
1774
1774
  lat: this.info.sysInfo.lat,
1775
1775
  lng: this.info.sysInfo.lng,
1776
1776
  area: this?.info?.sysInfo?.area,
1777
1777
  });
1778
1778
  } else {
1779
1779
  this.jmfeReayPromise().then(() => {
1780
1780
  this.getCacheAddressRouter()
1781
1781
  .then((res) => {
1782
1782
  const { status, data } = res;
1783
1783
  console.log('原生端获取经纬度原始数据结果', status, data);
1784
1784
  if (status === '0' && data) {
1785
1785
  const { lat, latitude, lng, longitude, provinceId, cityId, countyId, townId } =
1786
1786
  data || {};
1787
1787
  let area = '';
1788
1788
  this.info.sysInfo['lat'] = `${lat || latitude || ''}`;
1789
1789
  this.info.sysInfo['lng'] = `${lng || longitude || ''}`;
1790
1790
  if (provinceId) {
1791
1791
  area = `${provinceId}_${cityId || 0}_${countyId || 0}_${townId || 0}`;
1792
1792
  this.info.pageInfo['address'] = area;
1793
1793
  this.info.pageInfo['addressCommaStr'] = area.replace(/_/g, ',');
1794
1794
  Taro.eventCenter.trigger(
1795
1795
  TaroEventType.USER_AREA_UPDATE,
1796
1796
  this.info.pageInfo.address,
1797
1797
  );
1798
1798
  }
1799
1799
  resolve({
1800
1800
  lat: this.info.sysInfo['lat'],
1801
1801
  lng: this.info.sysInfo['lng'],
1802
1802
  area: area,
1803
1803
  });
1804
1804
  } else {
1805
1805
  typeof res === 'object' &&
1806
1806
  sgmCustomReport({
1807
1807
  type: 3,
1808
1808
  code: 'jdapp_getCacheAddress_info',
1809
1809
  msg: {
1810
1810
  title: '松果app内通过router协议获取用户地址及经纬度信息异常',
1811
1811
  jdAppVersion: jdAppVersionStr,
1812
1812
  ...res,
1813
1813
  },
1814
1814
  });
1815
1815
  resolve({ lat: '', lng: '', area: '' });
1816
1816
  }
1817
1817
  })
1818
1818
  .catch((e) => {
1819
1819
  console.log(' ~~ file: index.h5.ts:518 ~~ .catch ~~ e:', e);
1820
1820
  resolve({ lat: '', lng: '', area: '' });
1821
1821
  console.log('判断jmfe不存在,获取经纬度信息异常');
1822
1822
  });
1823
1823
  });
1824
1824
  }
1825
1825
  });
1826
1826
  }
1827
1827
 
1828
1828
  async updateMPaasConfigAsync(isBeforePageReady: boolean) {
1829
1829
  console.log('updateMPaasConfigAsync isBeforePageReady:', isBeforePageReady);
1830
1830
  if (!isJdApp) {
1831
1831
  return;
1832
1832
  }
1833
1833
  const avifSwitch = await getMPaasConfigByBussinessKey('avifSwitch', isBeforePageReady);
1834
1834
  this.info.sysInfo.dynamicConfig['avifSwitch'] = avifSwitch;
1835
1835
  const hybridHttpSwitch = await getMPaasConfigByBussinessKey(
1836
1836
  'hybridHttpSwitch',
1837
1837
  isBeforePageReady,
1838
1838
  );
1839
1839
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = hybridHttpSwitch;
1840
1840
  const isFollowAppVideoPlayStatus = await getMPaasConfigByBussinessKey(
1841
1841
  'isFollowAppVideoPlayStatus',
1842
1842
  isBeforePageReady,
1843
1843
  );
1844
1844
  console.log(
1845
1845
  'isBeforePageReady:',
1846
1846
  isBeforePageReady,
1847
1847
  'isFollowAppVideoPlayStatus:',
1848
1848
  isFollowAppVideoPlayStatus,
1849
1849
  );
1850
1850
  if (isFollowAppVideoPlayStatus === true || isFollowAppVideoPlayStatus === 'true') {
1851
1851
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = true;
1852
1852
  }
1853
1853
  }
1854
1854
 
1855
1855
  async getWifiVideoAutoPlayAsync() {
1856
1856
  this.info.sysInfo['wifiVideoAutoPlay'] = false;
1857
1857
  if (!isJdApp) {
1858
1858
  return;
1859
1859
  }
1860
1860
  const videoPlayStatus = await getWifiVideoAutoPlay().catch((e) => {
1861
1861
  return 0;
1862
1862
  });
1863
1863
  if (Number(videoPlayStatus) === 1) {
1864
1864
  this.info.sysInfo['wifiVideoAutoPlay'] = true;
1865
1865
  }
1866
1866
  }
1867
1867
 
1868
1868
  async getMPaasConfigAsync() {
1869
1869
  this.info.sysInfo.dynamicConfig = {};
1870
1870
  this.info.sysInfo.dynamicConfig['avifSwitch'] = {};
1871
1871
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = {};
1872
1872
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = false;
1873
1873
  return this.updateMPaasConfigAsync(true);
1874
1874
  }
1875
1875
 
1876
1876
  getDynamicConfig(key: string) {
1877
1877
  return this.info.sysInfo.dynamicConfig[key];
1878
1878
  }
1879
1879
  async updateMPaasConfig() {
1880
1880
  console.log('updateMPaasConfig');
1881
1881
  if (
1882
1882
  isIosDevice &&
1883
1883
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_VERSION) < 0 &&
1884
1884
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_LOW_VERSION) >= 0
1885
1885
  ) {
1886
1886
  try {
1887
1887
  await this.updateMPaasConfigAsync(false);
1888
1888
  } catch (e) {
1889
1889
  console.log('updateMPaasConfigAsync:', e);
1890
1890
  }
1891
1891
  }
1892
1892
  }
1893
1893
 
1894
1894
  toLogin(options) {
1895
1895
  return this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState
1896
1896
  ? this.toWxAppLogin(options)
1897
1897
  : this.toWebLogin(options);
1898
1898
  }
1899
1899
 
1900
1900
  doLogin(options) {
1901
1901
  return this.toLogin(options);
1902
1902
  }
1903
1903
 
1904
1904
  doLoginForJdPin(options = {}) {
1905
1905
  return this.doLogin({
1906
1906
  loginColor: {
1907
1907
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
1908
1908
  dpin: 0,
1909
1909
  },
1910
1910
  ...options,
1911
1911
  });
1912
1912
  }
1913
1913
 
1914
1914
  toWebLogin(options) {
1915
1915
  let params: {
1916
1916
  returnurl: string;
1917
1917
  } = {
1918
1918
  returnurl: '',
1919
1919
  };
1920
1920
  const loginUrl = isPc
1921
1921
  ? `//passport.jd.com/new/login.aspx`
1922
1922
  : `${domain.mobileLogin}/user/login.action`;
1923
1923
  const defaultParams = {
1924
1924
  appid: '100',
1925
1925
  returnurl: window.location.href,
1926
1926
  };
1927
1927
  if (isString(options)) {
1928
1928
  params = Object.assign({}, defaultParams, {
1929
1929
  returnurl: options,
1930
1930
  });
1931
1931
  } else if (isObject(options)) {
1932
1932
  const { loginColor, ...otherOptions } = options;
1933
1933
  params = Object.assign({}, defaultParams, otherOptions);
1934
1934
  } else {
1935
1935
  params = defaultParams;
1936
1936
  }
1937
1937
  params.returnurl = encodeURIComponent(params.returnurl);
1938
1938
  let getFullUrl = loginUrl + '?' + serialize(params);
1939
1939
  if (isPc) {
1940
1940
  getFullUrl = getFullUrl.replace(/returnurl/, 'ReturnUrl');
1941
1941
  }
1942
1942
  return Promise.resolve({
1943
1943
  h5ToUrl: true,
1944
1944
  url: getFullUrl,
1945
1945
  }).then(() => {
1946
1946
  window.location.href = getFullUrl;
1947
1947
  });
1948
1948
  }
1949
1949
 
1950
1950
  toWxAppLogin(options = {}) {
1951
1951
  console.log('微信京购小程序中h5登录跳转', options);
1952
1952
  return Promise.resolve(true).then(() => {
1953
1953
  const { loginColor } = Object.assign(
1954
1954
  {},
1955
1955
  {
1956
1956
  loginColor: {
1957
1957
  biz: WXAPP_BIZ_KEY,
1958
1958
  dpin: 1,
1959
1959
  },
1960
1960
  },
1961
1961
  options,
1962
1962
  );
1963
1963
  window.location.href = `${domain.wq}/pinbind/pintokenredirect?biz=${
1964
1964
  loginColor.biz
1965
1965
  }&url=${encodeURIComponent(window.location.href)}`;
1966
1966
  });
1967
1967
  }
1968
1968
 
1969
1969
  getLoginCookie() {
1970
1970
  return Promise.resolve({
1971
1971
  pin: cookie.get('pin') || '',
1972
1972
  });
1973
1973
  }
1974
1974
 
1975
1975
  clearLoginCookie() {
1976
1976
  cookie.remove('pin');
1977
1977
  }
1978
1978
 
1979
1979
  checkStatusAndLogin(options = {}) {
1980
1980
  if (!this.checkStatusAndLoginPromise) {
1981
1981
  this.checkStatusAndLoginPromise = new Promise(async (resolve, reject) => {
1982
1982
  try {
1983
1983
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
1984
1984
  if (getLoginState) {
1985
1985
  resolve(true);
1986
1986
  } else {
1987
1987
  this.toLogin(options);
1988
1988
  reject(false);
1989
1989
  }
1990
1990
  } catch (e) {
1991
1991
  this.toLogin(options);
1992
1992
  reject(false);
1993
1993
  }
1994
1994
  });
1995
1995
  return this.checkStatusAndLoginPromise;
1996
1996
  } else {
1997
1997
  return this.checkStatusAndLoginPromise
1998
1998
  .then(() => {
1999
1999
  return Promise.resolve(true);
2000
2000
  })
2001
2001
  .catch(() => {
2002
2002
  this.toLogin(options);
2003
2003
  return Promise.reject(true);
2004
2004
  });
2005
2005
  }
2006
2006
  }
2007
2007
 
2008
2008
  checkJdStatusAndLogin(
2009
2009
  options = {
2010
2010
  loginColor: {
2011
2011
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
2012
2012
  dpin: 0,
2013
2013
  },
2014
2014
  },
2015
2015
  ) {
2016
2016
  return this.checkStatusAndLogin(options);
2017
2017
  }
2018
2018
 
2019
2019
  doCheckLoginStateAndForApiCheck(options) {
2020
2020
  if (this.info.loginState) {
2021
2021
  return Promise.resolve(true);
2022
2022
  } else {
2023
2023
  return new Promise((resolve, reject) => {
2024
2024
  if (this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState) {
2025
2025
  const getWqAuthToken = cookie.get('wq_auth_token');
2026
2026
  const getWqSkey = cookie.get('wq_skey');
2027
2027
  const getWqUin = cookie.get('wq_uin');
2028
2028
  const isLoginState =
2029
2029
  options?.loginColor?.dpin === 0 ? getWqAuthToken : getWqSkey && getWqUin;
2030
2030
  if (isLoginState) {
2031
2031
  this.info.loginState = true;
2032
2032
  resolve(true);
2033
2033
  } else {
2034
2034
  reject(false);
2035
2035
  }
2036
2036
  } else {
2037
2037
  Taro.request({
2038
2038
  url: api.isLogin,
2039
2039
  jsonp: true,
2040
2040
  timeout: 3000,
2041
2041
  success: (res) => {
2042
2042
  const { statusCode, data } = res;
2043
2043
  if (statusCode === 200 && data?.islogin && Number(data.islogin) === 1) {
2044
2044
  this.info.loginState = true;
2045
2045
  resolve(true);
2046
2046
  } else {
2047
2047
  reject(false);
2048
2048
  }
2049
2049
  },
2050
2050
  fail: (err) => {
2051
2051
  console.log('登录检查异常', err);
2052
2052
  reject(false);
2053
2053
  },
2054
2054
  });
2055
2055
  }
2056
2056
  });
2057
2057
  }
2058
2058
  }
2059
2059
 
2060
2060
  checkLoginStatus(options) {
2061
2061
  return new Promise(async (resolve, reject) => {
2062
2062
  try {
2063
2063
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
2064
2064
  if (getLoginState) {
2065
2065
  const { pin } = await this.getLoginCookie();
2066
2066
  this.info.userInfo = {
2067
2067
  pin,
2068
2068
  encodePin: encodeURIComponent(pin),
2069
2069
  ptkey: '',
2070
2070
  };
2071
2071
  resolve(true);
2072
2072
  } else {
2073
2073
  reject(false);
2074
2074
  }
2075
2075
  } catch (e) {
2076
2076
  reject(false);
2077
2077
  }
2078
2078
  });
2079
2079
  }
2080
2080
 
2081
2081
  updatePageAndLogInfo(updateQuery = {}) {
2082
2082
  const createUpdateQueryInfo: {
2083
2083
  query: {
2084
2084
  shopId?: string | number;
2085
2085
  venderId?: string | number;
2086
2086
  };
2087
2087
  updateShopInfoState: boolean;
2088
2088
  } = Object.assign(
2089
2089
  {},
2090
2090
  {
2091
2091
  query: {},
2092
2092
  updateShopInfoState: false,
2093
2093
  },
2094
2094
  updateQuery,
2095
2095
  );
2096
2096
  console.log(
2097
2097
  '获取当前下发的店铺查询参数',
2098
2098
  updateQuery,
2099
2099
  '获取之前保存的shopInfo店铺查询参数',
2100
2100
  this.info?.shopInfo,
2101
2101
  );
2102
2102
  const { query, updateShopInfoState } = createUpdateQueryInfo;
2103
2103
  const { shopId, venderId, un_area } = query;
2104
2104
  if (updateShopInfoState) {
2105
2105
  this.info.queryInfo = {
2106
2106
  ...this.info.queryInfo,
2107
2107
  ...query,
2108
2108
  };
2109
2109
  if (shopId && venderId) {
2110
2110
  this.info.shopInfo = {
2111
2111
  shopId: `${shopId}`,
2112
2112
  venderId: `${venderId}`,
2113
2113
  };
2114
2114
  }
2115
2115
  } else {
2116
2116
  this.info.queryInfo = {
2117
2117
  ...query,
2118
2118
  };
2119
2119
  if (
2120
2120
  this.info.shopInfo?.shopId &&
2121
2121
  this.info.shopInfo?.venderId &&
2122
2122
  (this.info.shopInfo.shopId == shopId || this.info.shopInfo.venderId == venderId)
2123
2123
  ) {
2124
2124
  this.info.queryInfo.shopId = this.info.shopInfo.shopId;
2125
2125
  this.info.queryInfo.venderId = this.info.shopInfo.venderId;
2126
2126
  console.log(
2127
2127
  '当前存储的店铺shopId和venderId与下发的店铺信息shopId或者venderId为同一个,补充shopId或者venderId查询参数',
2128
2128
  this.info.queryInfo,
2129
2129
  );
2130
2130
  }
2131
2131
  }
2132
2132
  this.info.queryInfo['shopId'] &&
2133
2133
  (this.info.queryInfo['shopId'] = `${this.info.queryInfo['shopId']}`);
2134
2134
  this.info.queryInfo['venderId'] &&
2135
2135
  (this.info.queryInfo['venderId'] = `${this.info.queryInfo['venderId']}`);
2136
2136
  console.log(
2137
2137
  'h5==获取店铺下发查询参数\n',
2138
2138
  query,
2139
2139
  '\n获取店铺最后查询参数\n',
2140
2140
  this.info.queryInfo,
2141
2141
  '\n是否为更新店铺状态\n',
2142
2142
  updateShopInfoState,
2143
2143
  );
2144
2144
  const changeArea = un_area && un_area.length > 0 ? un_area : ipLoc_djd ? ipLoc_djd : '';
2145
2145
  if (changeArea) {
2146
2146
  this.info.pageInfo.address = changeArea;
2147
2147
  this.info.pageInfo.un_area = changeArea;
2148
2148
  this.info.pageInfo.addressCommaStr = changeArea.replace(/_/g, ',');
2149
2149
  }
2150
2150
  }
2151
2151
 
2152
2152
  dealLoadSdkList() {
2153
2153
  const globalLoadJsList = window?.shopGlobalSwitch?.asyncLoadJsList ?? [];
2154
2154
  const businessLoadJsList = window?.PAGE_DATA?.businessData?.asyncLoadJsList ?? [];
2155
2155
  const concatLoadJsList = [].concat(globalLoadJsList, businessLoadJsList);
2156
2156
  let mergeLoadJsList = globalLoadJsList;
2157
2157
  try {
2158
2158
  mergeLoadJsList = concatLoadJsList.reduce((accArr: any[], current: any) => {
2159
2159
  const getFindIndex = accArr.findIndex((item) => item?.fileName === current?.fileName);
2160
2160
  getFindIndex !== -1
2161
2161
  ? (accArr[getFindIndex] = { ...accArr[getFindIndex], ...current })
2162
2162
  : accArr.push(current);
2163
2163
  return accArr;
2164
2164
  }, []);
2165
2165
  } catch (e) {
2166
2166
  console.log('LoadJsList合并错误', e);
2167
2167
  }
2168
2168
  console.log(
2169
2169
  'globalLoadJsList',
2170
2170
  globalLoadJsList,
2171
2171
  'businessLoadJsList',
2172
2172
  businessLoadJsList,
2173
2173
  '两个加载jsList集合合并完成',
2174
2174
  mergeLoadJsList,
2175
2175
  );
2176
2176
  this.loadJsSdkList = mergeLoadJsList;
2177
2177
  return this.loadJsSdkList;
2178
2178
  }
2179
2179
 
2180
2180
  renderNextTickLoadSdk() {
2181
2181
  Taro.nextTick(() => {
2182
2182
  console.log(
2183
2183
  '页面渲染的下一帧执行的js加载方法,当前nextTick存在state的渲染问题,先延迟1s=======',
2184
2184
  );
2185
2185
  setTimeout(() => {
2186
2186
  this.loadOtherSdk(LoadJsInitTriggerType.NRXT_TICK, this.loadJsSdkList);
2187
2187
  }, 1000);
2188
2188
  });
2189
2189
  }
2190
2190
 
2191
2191
  loadOtherSdk(triggerType = LoadJsInitTriggerType.NOW, loadJsList: any[] = []) {
2192
2192
  const getLoadJsList =
2193
2193
  Array.isArray(loadJsList) && loadJsList.length > 0 ? loadJsList : this.dealLoadSdkList();
2194
2194
  const getLoadFilterList = getLoadJsList.filter((item) => {
2195
2195
  const getInitLoadEnvType = item?.initLoadEnvType || LoadJsInitLoadEnvType.ALL;
2196
2196
  let getLoastLoadEventState = true;
2197
2197
  if (getInitLoadEnvType === LoadJsInitLoadEnvType.JD_APP) {
2198
2198
  getLoastLoadEventState = isJdApp;
2199
2199
  }
2200
2200
  else if (getInitLoadEnvType === LoadJsInitLoadEnvType.M) {
2201
2201
  getLoastLoadEventState = !isJdApp || !!isJdAndHarmonyDevice;
2202
2202
  }
2203
2203
  const getInitTriggerType =
2204
2204
  isJdApp && item?.initJdAppTriggerType
2205
2205
  ? item?.initTriggerType
2206
2206
  : item?.initTriggerType || LoadJsInitTriggerType.NOW;
2207
2207
  const getInitLinkTriggerWay = window?.PAGE_DATA[item?.initLinkTriggerWay] || false;
2208
2208
  return getLoastLoadEventState && getInitTriggerType === triggerType && getInitLinkTriggerWay;
2209
2209
  });
2210
2210
  console.log(
2211
2211
  '获取当前触发方式',
2212
2212
  triggerType,
2213
2213
  '获取当前最后加载的js集合',
2214
2214
  getLoadFilterList,
2215
2215
  '过滤前的加载集合',
2216
2216
  getLoadJsList,
2217
2217
  );
2218
2218
  getLoadFilterList.length > 0 &&
2219
2219
  getLoadFilterList.forEach((item) => {
2220
2220
  const isLoadState = /sgm/.test(item?.fileName)
2221
2221
  ? window?.shopGlobalSwitch?.openSgm === 'true'
2222
2222
  : true;
2223
2223
  isLoadState &&
2224
2224
  this.loadItemSdkPromise(item)
2225
2225
  .then((res) => {
2226
2226
  console.info('当前js地址' + item?.src, '加载状态', res);
2227
2227
  const isFileNameNewDraSdkJs = res?.fileName === 'newDraSdkJs';
2228
2228
  if (isFileNameNewDraSdkJs && window?.dra?.run) {
2229
2229
  window.dra.run('init', { aid: res?.aid });
2230
2230
  window.dra.run('start');
2231
2231
  }
2232
2232
  })
2233
2233
  .catch((err) => {
2234
2234
  console.info('当前js地址加载异常', item?.src);
2235
2235
  window?.fetchErrorData &&
2236
2236
  window.fetchErrorData({
2237
2237
  title: '公共js加载异常',
2238
2238
  type: 'jsLoad',
2239
2239
  data: err,
2240
2240
  });
2241
2241
  });
2242
2242
  });
2243
2243
  }
2244
2244
  loadScriptEle(jsInfo, resolve, reject) {
2245
2245
  const getFileName = jsInfo?.fileName;
2246
2246
  if (getFileName) {
2247
2247
  const getEleId = `J_loadJs_${getFileName}`;
2248
2248
  const getEle = document.getElementById(getEleId);
2249
2249
  if (!getEle) {
2250
2250
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
2251
2251
  const _sgmEle = document.createElement('script');
2252
2252
  _sgmEle.id = getEleId;
2253
2253
  _sgmEle.onload = function () {
2254
2254
  resolve({
2255
2255
  ...jsInfo,
2256
2256
  jsTip: 'js加载成功',
2257
2257
  });
2258
2258
  };
2259
2259
  _sgmEle.onerror = function () {
2260
2260
  reject({
2261
2261
  ...jsInfo,
2262
2262
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2263
2263
  jsReqError: '当前js创建标签触发onerror异常回调,请排查网络络错误或语法错误或运行时错误',
2264
2264
  });
2265
2265
  };
2266
2266
  const dataAttrList = ['timeout', 'fileName', 'env'];
2267
2267
  const getJsInfoKeyList = Object.keys(jsInfo);
2268
2268
  getJsInfoKeyList.forEach((key) => {
2269
2269
  if (key === 'async') {
2270
2270
  _sgmEle.async = jsInfo[key];
2271
2271
  } else if (key === 'crossOrigin') {
2272
2272
  _sgmEle.crossOrigin = jsInfo[key];
2273
2273
  } else if (key === 'src') {
2274
2274
  _sgmEle.src = `${jsInfo[key]}`;
2275
2275
  } else if (dataAttrList.includes(key) || /init/.test(key)) {
2276
2276
  _sgmEle.setAttribute(`data-${key}`, jsInfo[key]);
2277
2277
  } else {
2278
2278
  _sgmEle.setAttribute(key, jsInfo[key]);
2279
2279
  }
2280
2280
  });
2281
2281
  document.head.appendChild(_sgmEle);
2282
2282
  } else {
2283
2283
  console.log(`当前${jsInfo?.fileName || 'js'}已经存在页面中,可以直接调用相关方法`, jsInfo);
2284
2284
  resolve({
2285
2285
  ...jsInfo,
2286
2286
  jsTip: 'js本身已存在页面中',
2287
2287
  });
2288
2288
  }
2289
2289
  } else {
2290
2290
  console.warn('当前js资源信息缺少必要的参数fileName,请关注', jsInfo);
2291
2291
  }
2292
2292
  }
2293
2293
 
2294
2294
  loadItemSdkPromise(jsInfo = {}) {
2295
2295
  if (jsInfo?.src) {
2296
2296
  const getInitLoadType =
2297
2297
  isJdApp && jsInfo?.initJdAppLoadType
2298
2298
  ? jsInfo?.initJdAppLoadType
2299
2299
  : jsInfo?.initLoadType || LoadJsInitLoadType.ALL;
2300
2300
  if (getInitLoadType !== LoadJsInitLoadType.NONE) {
2301
2301
  const getFileKeyName = jsInfo?.fileName || jsInfo?.src;
2302
2302
  if (!this.loadJsSdkListCachePromise[getFileKeyName]) {
2303
2303
  if (getInitLoadType !== LoadJsInitLoadType.INSERT_ELE) {
2304
2304
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
2305
2305
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
2306
2306
  try {
2307
2307
  const jsXhrRequest = new XMLHttpRequest();
2308
2308
  jsXhrRequest.timeout = jsInfo?.timeout ?? 2000;
2309
2309
  const jsUrl = `${jsInfo?.src}`;
2310
2310
  jsXhrRequest.open('GET', jsUrl, true);
2311
2311
  jsXhrRequest.onreadystatechange = () => {
2312
2312
  if (jsXhrRequest.readyState === 4) {
2313
2313
  const getReqStatus = jsXhrRequest.status;
2314
2314
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
2315
2315
  const getInsetHeadState = getInitLoadType === LoadJsInitLoadType.ALL;
2316
2316
  if (getInsetHeadState) {
2317
2317
  this.loadScriptEle(jsInfo, resolve, reject);
2318
2318
  } else {
2319
2319
  resolve({
2320
2320
  ...jsInfo,
2321
2321
  jsTip: 'js请求成功,暂未插入head节点,业务自行单独插入',
2322
2322
  });
2323
2323
  }
2324
2324
  getReqStatus !== 200 &&
2325
2325
  sgmCustomReport({
2326
2326
  type: 3,
2327
2327
  code: 'js_load_special_code',
2328
2328
  msg: {
2329
2329
  msg: '当前js加载成功,状态非200,特殊上报观察',
2330
2330
  jsReqState: getReqStatus,
2331
2331
  env: getSgmCustomCode('js_load_special_code'),
2332
2332
  data: jsInfo,
2333
2333
  },
2334
2334
  });
2335
2335
  } else {
2336
2336
  const getRes = {
2337
2337
  ...jsInfo,
2338
2338
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2339
2339
  jsReqError: `请求状态异常,状态码为${getReqStatus}`,
2340
2340
  jsReqState: getReqStatus,
2341
2341
  };
2342
2342
  console.log('当前js请求状态异常,具体信息见', getRes);
2343
2343
  reject(getRes);
2344
2344
  }
2345
2345
  }
2346
2346
  };
2347
2347
  jsXhrRequest.onerror = () => {
2348
2348
  const getRes = {
2349
2349
  ...jsInfo,
2350
2350
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2351
2351
  jsReqError: '请求错误',
2352
2352
  };
2353
2353
  console.log('当前js请求错误', getRes);
2354
2354
  jsXhrRequest.abort();
2355
2355
  reject(getRes);
2356
2356
  };
2357
2357
  jsXhrRequest.ontimeout = () => {
2358
2358
  const getRes = {
2359
2359
  ...jsInfo,
2360
2360
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2361
2361
  jsReqError: `请求${jsXhrRequest.timeout}ms超时异常`,
2362
2362
  jsReqState: jsXhrRequest.status,
2363
2363
  };
2364
2364
  console.log('当前js请求超时异常', getRes);
2365
2365
  jsXhrRequest.abort();
2366
2366
  reject(getRes);
2367
2367
  };
2368
2368
  jsXhrRequest.send();
2369
2369
  } catch (e) {
2370
2370
  console.log('执行js请求异常', e);
2371
2371
  reject({
2372
2372
  ...jsInfo,
2373
2373
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2374
2374
  jsReqError: '未知异常',
2375
2375
  error: e,
2376
2376
  });
2377
2377
  }
2378
2378
  });
2379
2379
  } else {
2380
2380
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
2381
2381
  return this.loadScriptEle(jsInfo, resolve, reject);
2382
2382
  });
2383
2383
  }
2384
2384
  }
2385
2385
  return this.loadJsSdkListCachePromise[getFileKeyName];
2386
2386
  } else {
2387
2387
  return Promise.resolve({
2388
2388
  ...jsInfo,
2389
2389
  jsTip: 'js加载方式设置为不加载,当前不做处理',
2390
2390
  });
2391
2391
  }
2392
2392
  } else {
2393
2393
  return Promise.reject(jsInfo);
2394
2394
  }
2395
2395
  }