@conecli/cone-render 0.10.1-shop3.116 → 0.10.1-shop3.117

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
  BUSINESS_TYPE,
3
2
  cacheAppKey,
4
3
  cacheAppUuidKey,
5
4
  cacheH5LbsAddressKey,
6
5
  JSSDK_APP_WEBVIEW_CODE,
7
6
  LoadJsInitLoadEnvType,
8
7
  LoadJsInitLoadType,
9
8
  LoadJsInitTriggerType,
10
9
  MPAAS_CONFIG_APP_LOW_VERSION,
11
10
  MPAAS_CONFIG_APP_VERSION,
12
11
  SECTION_HOME_TAB_NAME_TYPE,
13
12
  SECTION_HOME_TAB_TYPE,
14
13
  TaroEventType,
15
14
  WX_BUSINESS_TYPE,
16
15
  WXAPP_BIZ_KEY,
17
16
  WXAPP_BIZ_SHOP_LIGHT_KEY,
18
17
  languageTypeList,
19
18
  getSystemInfos,
20
19
  getTaroStorageKeyValue,
21
20
  ipLoc_djd,
22
21
  setTaroStorage,
23
22
  isInJdAppH5DebugMode,
24
23
  callRouterAndroid,
25
24
  callRouterIOS,
26
25
  getMPaasConfigByBussinessKey,
27
26
  dealNativePixelToCssPixel,
28
27
  draBusinessCustomReport,
29
28
  draBusinessCustomLogReport,
30
29
  isAndroidDevice,
31
30
  isH5AndJingGouMini,
32
31
  isIosDevice,
33
32
  isJdAndAndroidDevice,
34
33
  isObject,
35
34
  isPc,
36
35
  isString,
37
36
  jdAppVersion,
38
37
  jdAppVersionStr,
39
38
  serialize,
40
39
  languageNowType,
41
40
  urlCookie,
42
41
  isAscfApp,
43
42
  jdAppVersionCompare,
44
43
  parseQueryUrlObj,
45
44
  abTestLabels: {},
46
45
  nonSellableSkuids: {},
47
46
  loginState: false,
48
47
  cookiesStr: '',
49
48
  userInfo: userPinKey,
50
49
  isImmersive:
51
50
  !window?.shopGlobalSwitch?.disableImmersive &&
52
51
  isJdApp &&
53
52
  window.location?.search.includes('immersive=1'),
54
53
  isJingGouMiniViewState: false,
55
54
  isJingxiMiniViewState: false,
56
55
  baseAddCartSwitch: true,
57
56
  pageInfo: {
58
57
  wxBusinessType: WX_BUSINESS_TYPE.NO,
59
58
  address: '',
60
59
  addressCommaStr: '',
61
60
  fullAddress: '',
62
61
  un_area: '',
63
62
  userLbsAddress: '',
64
63
  vapptype: '1',
65
64
  pageType: 'home',
66
65
  isExposureState: false,
67
66
  moduleId: '',
68
67
  entrance: '',
69
68
  dataType: BUSINESS_TYPE.ONLINE,
70
69
  floorExposureInfo: {},
71
70
  floorVideInfo: {},
72
71
  productVideInfo: {},
73
72
  tabsLoadAllDataInfo: {
74
73
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: false,
75
74
  },
76
75
  updateShopInfosAllState: false,
77
76
  isVipShop: false,
78
77
  isJdShowNativeImmersivePlayer: false,
79
78
  isSuperBrandShop: false,
80
79
  ...shopConfig,
81
80
  pageScrollTop: 0,
82
81
  pageIdxHeightInfo: {
83
82
  list: [],
84
83
  },
85
84
  shopNavBarHeight: 0,
86
85
  },
87
86
  defaultQueryLogInfo: {
88
87
  sourceType: 'JDshop',
89
88
  sourceValue: '',
90
89
  moduleId: 'none',
91
90
  entrance: 'none',
92
91
  },
93
92
  sysInfo: {
94
93
  windowWidth: isPc ? 375 : 0,
95
94
  containerWidth: isPc ? 375 : 0,
96
95
  windowHeight: 0,
97
96
  netWorkType: '4g',
98
97
  jdBottomBarHeight: 0,
99
98
  jdNativeHeaderHeight: 0,
100
99
  isJdTabletDevice: false,
101
100
  isJdTabletLandscape: false,
102
101
  },
103
102
  queryInfo: {},
104
103
  shopInfo: {},
105
104
  openAppData: {},
106
105
  public info: CommonInterFace.BaseConfigInfo;
107
106
  public config: {
108
107
  [key: string]: any;
109
108
  };
110
109
  public lazyContainer: CommonInterFace.lazyContainer;
111
110
  public renderedIsvComponents: CommonInterFace.renderedIsvComponents;
112
111
  public rootEleNode: HTMLElement | null;
113
112
  public checkStatusAndLoginPromise: object | null;
114
113
  private jmfeRegisterStatePromise: Promise<any> | null;
115
114
  private jdScreenSizeInfoPromise: Promise<any> | null;
116
115
  private rootEleWidthRegisterPromise: Promise<any> | null;
117
116
  private loadJsH5tagStatePromise: Promise<any> | null;
118
117
  private loadJsApiRequestStatePromise: Promise<any> | null;
119
118
  private jmfeRegisterState: boolean;
120
119
  public loadJsSdkList: {
121
120
  src: string;
122
121
  timeout: number;
123
122
  fileName: string;
124
123
  initTriggerType: typeof LoadJsInitTriggerType;
125
124
  initLinkTriggerWay:
126
125
  | 'asyncLoadAppSdkJs'
127
126
  | 'asyncLoadHandlerJs'
128
127
  | 'asyncLoadReportJs'
129
128
  | 'asyncLoadMtkJs'
130
129
  | 'asyncLoadSecurityJs'
131
130
  | 'asyncLoadSgmJs'
132
131
  | 'asyncLoadCartJs'
133
132
  | 'asyncLoadNewDraSdkJs'
134
133
  | 'asyncLoadH5TagJs';
135
134
  initLoadEnvType: typeof LoadJsInitLoadEnvType;
136
135
  defer?: 'true';
137
136
  async?: 'true';
138
137
  crossOrigin: 'anonymous' | '';
139
138
  }[];
140
139
  public loadJsSdkListCachePromise: any;
141
140
  public rootEleInitWidth: number;
142
141
  public lbsAddressCachePromise: Promise<any> | null;
143
142
  public languageCacheProimse: Promise<any> | null;
144
143
  public languageJsonData: any | null;
145
144
  public businessWorkerReady: boolean;
146
145
  public businessWorkerReadyPromise: Promise<any> | null;
147
146
  public workerPreRequestData = new Map<string, any>();
148
147
  constructor(opt) {
149
148
  this.info = this._getConfig(opt);
150
149
  this.config = {};
151
150
  this.loadJsSdkList = [];
152
151
  this.loadJsSdkListCachePromise = {};
153
152
  this.lazyContainer = {
154
153
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: {
155
154
  appLazyContainerList: [],
156
155
  appLazyFinishContainerList: [],
157
156
  },
158
157
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_PROMOTION]]: {
159
158
  appLazyContainerList: [],
160
159
  appLazyFinishContainerList: [],
161
160
  },
162
161
  };
163
162
  this.renderedIsvComponents = {};
164
163
  this.rootEleNode = document.querySelector('body');
165
164
  this.checkStatusAndLoginPromise = null;
166
165
  this.jmfeRegisterStatePromise = null;
167
166
  this.jdScreenSizeInfoPromise = null;
168
167
  this.rootEleWidthRegisterPromise = null;
169
168
  this.lbsAddressCachePromise = null;
170
169
  this.languageCacheProimse = null;
171
170
  this.businessWorkerReady = false;
172
171
  this.businessWorkerReadyPromise = null;
173
172
  this.loadJsH5tagStatePromise = null;
174
173
  this.loadJsApiRequestStatePromise = null;
175
174
  this.workerPreRequestData = new Map<string, any>();
176
175
  this.languageJsonData = langeJsonDataForCn;
177
176
  this.rootEleInitWidth = this.getRootEleWindowWidthInfo().getRootEleWidth || -1;
178
177
  this._init();
179
178
  if (isJdApp) {
180
179
  this.jmfeReayPromise().then(() => {
181
180
  this.jdWorkerReadyPromise();
182
181
  initAccessibility();
183
182
  });
184
183
  this._getJdPadMinWidthForListen() && this.getPadWindowRootEleWidthPromise();
185
184
  }
186
185
  }
187
186
  _getConfig(opt) {
188
187
  return Object.assign({}, DefaultConfig, opt);
189
188
  }
190
189
  _init() {
191
190
  this.loadOtherSdk();
192
191
  this.checkJdAddCartState();
193
192
  this.checkPageDomHeightToReport();
194
193
  }
195
194
  checkPageDomHeightToReport() {
196
195
  Taro.nextTick(() => {
197
196
  setTimeout(() => {
198
197
  const getReportData = {
199
198
  containerFloorLisHeight: -1,
200
199
  appHeight: -1,
201
200
  };
202
201
  const getAppEle = document.getElementById('app');
203
202
  const getFloorContainerEle = document.getElementById('J_shopContainerFloorList');
204
203
  const getNetWorkEle = document.querySelector('.J_shopNetwork');
205
204
  getFloorContainerEle &&
206
205
  (getReportData.containerFloorLisHeight =
207
206
  getFloorContainerEle?.getBoundingClientRect()?.height ?? -1);
208
207
  getAppEle && (getReportData.appHeight = getAppEle?.getBoundingClientRect()?.height ?? -1);
209
208
  const getMaxHeight = Math.max(
210
209
  getReportData.appHeight,
211
210
  getReportData.containerFloorLisHeight,
212
211
  );
213
212
  if (!getNetWorkEle && getMaxHeight > -1 && getMaxHeight < 80) {
214
213
  draBusinessCustomReport({
215
214
  eventName: 'business',
216
215
  errorName: 'pageDomHeightErrorCheck',
217
216
  errorMessage:
218
217
  '当前页面总高度异常小于80px,没有兜底network组件,可能空窗,请检查核对详细信息',
219
218
  extraData: JSON.stringify({
220
219
  data: getReportData,
221
220
  isJdApp,
222
221
  }),
223
222
  });
224
223
  }
225
224
  }, window?.shopGlobalSwitch?.checkPageDomHeightTime || 4000);
226
225
  });
227
226
  }
228
227
 
229
228
  checkJdAddCartState() {
230
229
  const getJdAppForNotMainRemoveCartUaList = isJdApp
231
230
  ? window?.PAGE_DATA?.businessData?.jdAppForNotMainRemoveCartUaList
232
231
  : undefined;
233
232
  if (
234
233
  getJdAppForNotMainRemoveCartUaList &&
235
234
  Array.isArray(getJdAppForNotMainRemoveCartUaList) &&
236
235
  getJdAppForNotMainRemoveCartUaList.length > 0
237
236
  ) {
238
237
  const setFilterReg = new RegExp(getJdAppForNotMainRemoveCartUaList.join('|'), 'i');
239
238
  this.info.baseAddCartSwitch = !setFilterReg.test(window.navigator.userAgent);
240
239
  }
241
240
  }
242
241
 
243
242
  loadApiSafeSteadyReayPromise() {
244
243
  if (!this.loadJsApiRequestStatePromise) {
245
244
  this.loadJsApiRequestStatePromise = this.loadOtherSdk(LoadJsInitTriggerType.API_REQUEST);
246
245
  }
247
246
  return this.loadJsApiRequestStatePromise;
248
247
  }
249
248
 
250
249
  loadH5tagReayPromise() {
251
250
  if (!this.loadJsH5tagStatePromise) {
252
251
  const h5TagJs = this.loadJsSdkList.find((e) => e.fileName === 'h5TagJs');
253
252
  this.loadJsH5tagStatePromise = !h5TagJs
254
253
  ? Promise.resolve(true)
255
254
  : this.loadOtherSdk(LoadJsInitTriggerType.NOW, [
256
255
  Object.assign({}, h5TagJs, {
257
256
  initTriggerType: LoadJsInitTriggerType.NOW,
258
257
  }),
259
258
  ]);
260
259
  }
261
260
  return this.loadJsH5tagStatePromise;
262
261
  }
263
262
 
264
263
  jmfeReayPromise(): Promise<any> {
265
264
  if (isJdApp) {
266
265
  if (this.jmfeRegisterState) {
267
266
  return Promise.resolve(true);
268
267
  } else {
269
268
  !this.jmfeRegisterStatePromise &&
270
269
  (this.jmfeRegisterStatePromise = new Promise((resolve, reject) => {
271
270
  ready('jmfe', 3000)
272
271
  .then(() => {
273
272
  window?.jmfe && window.jmfe.registerCode(JSSDK_APP_WEBVIEW_CODE);
274
273
  this.jmfeRegisterState = true;
275
274
  resolve(true);
276
275
  console.log(
277
276
  '松果app内初始化注册jmfe认证完成',
278
277
  window?.jmfe,
279
278
  '当前版本',
280
279
  window?.jmfe?.VERSION,
281
280
  );
282
281
  })
283
282
  .catch((err) => {
284
283
  console.error('jmfe ready error', err);
285
284
  reject(false);
286
285
  });
287
286
  }));
288
287
  return this.jmfeRegisterStatePromise;
289
288
  }
290
289
  } else {
291
290
  return Promise.reject(false);
292
291
  }
293
292
  }
294
293
 
295
294
  jdMarkWorkerReady(resolve: (value: any) => void, source: string) {
296
295
  if (!this.businessWorkerReady) {
297
296
  const getResTime = Date.now();
298
297
  console.info(`jd worker注册成功,当前注册成功为${source}返回,时间:${getResTime}`);
299
298
  draBusinessCustomLogReport(
300
299
  `APP店铺业务worker注册成功,当前注册成功为${source}返回,时间戳${getResTime}, 后续业务请求可以用worker发送,内部走原生请求`,
301
300
  );
302
301
  this.businessWorkerReady = true;
303
302
  resolve(true);
304
303
  }
305
304
  }
306
305
 
307
306
  jdWorkerListenMsgData(workerData, thisTime,workerReadyState = true){
308
307
  if (workerData && workerData?.workerType) {
309
308
  const {
310
309
  functionId,
311
310
  postEndTime,
312
311
  postStartTime,
313
312
  originWorkerType,
314
313
  workerType,
315
314
  } = workerData;
316
315
  if (
317
316
  functionId &&
318
317
  originWorkerType === TaroEventType.jdWorkerPreRequest &&
319
318
  postStartTime &&
320
319
  postEndTime
321
320
  ) {
322
321
  const getMsg = `APP店铺业务worker请求返回结果成功,workerReady状态${workerReadyState},当前为${originWorkerType === workerType ?
323
322
  '预请求' :
324
323
  '第1次主动请求(因预请求在webview加载过程中未返回)'},functionId是${functionId},接口请求耗时${
325
324
  postEndTime - postStartTime
326
325
  }ms,接口传输到h5耗时${
327
326
  thisTime - postEndTime
328
327
  }ms,postStartTime为${postStartTime},postEndTime为${postEndTime},getResTime为${thisTime}`
329
328
  console.info(getMsg);
330
329
  draBusinessCustomLogReport(getMsg);
331
330
  }
332
331
  if (workerType === TaroEventType.jdWorkerPreRequest) {
333
332
  this.workerPreRequestData.set(workerData?.functionId, workerData);
334
333
  Taro.eventCenter.trigger(workerType, workerData);
335
334
  } else if (workerType === TaroEventType.jdWorkerRequest) {
336
335
  Taro.eventCenter.trigger(workerType, workerData);
337
336
  }
338
337
  }
339
338
  }
340
339
 
341
340
  jdWorkerReadyPromise(): Promise<any> {
342
341
  if (isJdApp) {
343
342
  if (this.businessWorkerReady) {
344
343
  return Promise.resolve(true);
345
344
  } else {
346
345
  const getOpenJdWorkerState =
347
346
  window?.PAGE_DATA?.businessData?.businessWorkerVersion &&
348
347
  versionCompare(
349
348
  jdAppVersionStr,
350
349
  window?.shopGlobalSwitch?.jdAppWorkerOpenVersion || '15.3.10',
351
350
  ) >= 0;
352
351
  !this.businessWorkerReadyPromise &&
353
352
  (this.businessWorkerReadyPromise = getOpenJdWorkerState
354
353
  ? new Promise((resolve) => {
355
354
  this.jmfeReayPromise()
356
355
  .then(() => {
357
356
  window.jmfe
358
357
  .onMsgForWorker(
359
358
  { version_code: window?.PAGE_DATA?.businessData?.businessWorkerVersion },
360
359
  (workerData) => {
361
360
  const getResTime = Date.now();
362
361
  console.info('收到jd worker消息:', workerData,"收到时间",getResTime,"workerReady状态", this.businessWorkerReady);
363
362
  this.jdWorkerListenMsgData(workerData, getResTime,this.businessWorkerReady)
364
363
  },
365
364
  )
366
365
  .then(() => {
367
366
  this.jdMarkWorkerReady(resolve,"then")
368
367
  })
369
368
  .catch((error) => {
370
369
  if(!this.businessWorkerReady){
371
370
  console.info(
372
371
  'jd worker注册失败,可能是客户端不支持worker,或者worker.js文件加载失败等原因。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑',
373
372
  error,
374
373
  );
375
374
  draBusinessCustomReport({
376
375
  eventName: 'business',
377
376
  errorName: 'jmfe_onMsgForWorker_error',
378
377
  errorMessage: `jd worker注册失败,可能是客户端不支持worker,或者worker.js文件加载失败等原因。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑`,
379
378
  extraData: JSON.stringify({
380
379
  businessWorkerVersion:
381
380
  window?.PAGE_DATA?.businessData?.businessWorkerVersion,
382
381
  error,
383
382
  time: Date.now(),
384
383
  }),
385
384
  });
386
385
  !window?.PAGE_DATA?.businessData
387
386
  ?.forbidJdWorkerErrorLoadApiSafeSteadyReay &&
388
387
  this.loadApiSafeSteadyReayPromise();
389
388
  resolve(false);
390
389
  }
391
390
  });
392
391
  })
393
392
  .catch((error) => {
394
393
  console.info('jmfe超时异常,worker注册失败', error);
395
394
  draBusinessCustomReport({
396
395
  eventName: 'business',
397
396
  errorName: 'jmfe_onMsgForWorker_error',
398
397
  errorMessage: `jd worker注册失败,原因是jmfe超时异常。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑`,
399
398
  extraData: JSON.stringify({
400
399
  businessWorkerVersion:
401
400
  window?.PAGE_DATA?.businessData?.businessWorkerVersion,
402
401
  error,
403
402
  }),
404
403
  });
405
404
  !window?.PAGE_DATA?.businessData?.forbidJdWorkerErrorLoadApiSafeSteadyReay &&
406
405
  this.loadApiSafeSteadyReayPromise();
407
406
  resolve(false);
408
407
  });
409
408
  })
410
409
  : Promise.resolve(false));
411
410
  }
412
411
  return this.businessWorkerReadyPromise;
413
412
  } else {
414
413
  return Promise.resolve(false);
415
414
  }
416
415
  }
417
416
 
418
417
  taskTimeoutPromise(callBack, timeout = 2000) {
419
418
  return new Promise((resolve) => {
420
419
  setTimeout(
421
420
  () => {
422
421
  const getCallBackRes = typeof callBack === 'function' && callBack();
423
422
  return resolve(getCallBackRes || false);
424
423
  },
425
424
  isInJdAppH5DebugMode ? 0 : timeout,
426
425
  );
427
426
  });
428
427
  }
429
428
  _getJdPadMinWidthForListen() {
430
429
  return (
431
430
  isJdApp &&
432
431
  Math.min(window.screen.width, window.screen.height) >
433
432
  (window?.shopGlobalSwitch?.checkPadRootEleMinWidth || 600)
434
433
  );
435
434
  }
436
435
 
437
436
  getJdScreenSizeInfoPromise() {
438
437
  !this.jdScreenSizeInfoPromise &&
439
438
  (this.jdScreenSizeInfoPromise = new Promise((resolve) => {
440
439
  const getThisTime = Date.now();
441
440
  this.jmfeReayPromise().then(() => {
442
441
  return Promise.race([
443
442
  window.jmfe.getScreenSize(),
444
443
  this.taskTimeoutPromise(() => {
445
444
  return {
446
445
  status: '-10',
447
446
  msg: '获取大屏信息2s超时',
448
447
  };
449
448
  }),
450
449
  ])
451
450
  .then((res) => {
452
451
  console.warn('===获取app大屏信息====', res);
453
452
  const { status, data } = res;
454
453
  if (status === '0' && data) {
455
454
  const { sizeType, isLandscape, pageHeight, pageWidth } = data;
456
455
  const getPageInfo = dealNativePixelToCssPixel({
457
456
  pageWidth,
458
457
  pageHeight,
459
458
  });
460
459
  this.info.sysInfo.jdScreenSizeType = sizeType;
461
460
  const getUseTime = Date.now() - getThisTime;
462
461
  console.warn(
463
462
  '===计算是否是app大屏信息,需满足宽度最新720===',
464
463
  getPageInfo,
465
464
  '原始数据',
466
465
  data,
467
466
  '是否是横屏isLandscape为1=',
468
467
  isLandscape,
469
468
  '用时',
470
469
  getUseTime,
471
470
  );
472
471
  if (getPageInfo?.pageWidth > 0) {
473
472
  this.rootEleInitWidth = getPageInfo?.pageWidth;
474
473
  draBusinessCustomReport({
475
474
  eventName: 'UIInteract',
476
475
  errorName: 'rootEle_width_getJdScreenSizeInfo',
477
476
  errorMessage: `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果,用时${getUseTime}`,
478
477
  extraData: JSON.stringify({
479
478
  isJdApp,
480
479
  getPageInfo,
481
480
  originData: res,
482
481
  }),
483
482
  });
484
483
  resolve(getPageInfo);
485
484
  } else {
486
485
  resolve({
487
486
  pageWidth: 0,
488
487
  pageHeight: 0,
489
488
  msg: '转换异常',
490
489
  });
491
490
  }
492
491
  } else {
493
492
  resolve({
494
493
  pageWidth: 0,
495
494
  pageHeight: 0,
496
495
  msg: '获取大屏信息异常或者超时',
497
496
  });
498
497
  }
499
498
  })
500
499
  .catch((err) => {
501
500
  console.log('获取大屏信息异常', err);
502
501
  resolve({
503
502
  pageWidth: 0,
504
503
  pageHeight: 0,
505
504
  msg: '获取大屏信息异常',
506
505
  });
507
506
  });
508
507
  });
509
508
  }));
510
509
  return this.jdScreenSizeInfoPromise;
511
510
  }
512
511
 
513
512
  listenJdTabletScreenChange() {
514
513
  this.jmfeReayPromise().then(() => {
515
514
  try {
516
515
  console.log('初始化监听大屏信息变化', window.jmfe.listenDeviceScreenChange);
517
516
  window.jmfe.listenDeviceScreenChange((event) => {
518
517
  console.log(
519
518
  '监听app大屏信息变化,orientation为landscape表示横屏,multiScreen为1表示android端分屏',
520
519
  event,
521
520
  '通过前端判断是不是横屏',
522
521
  window.matchMedia('(orientation: landscape)')?.matches,
523
522
  );
524
523
  const { orientation } = event?.data;
525
524
  if (orientation) {
526
525
  this.info.sysInfo.isJdTabletLandscape = orientation === 'landscape';
527
526
  Taro.eventCenter.trigger(
528
527
  TaroEventType.TABLE_SCREEN_CHANGE,
529
528
  this.info.sysInfo.isJdTabletLandscape,
530
529
  orientation,
531
530
  );
532
531
  }
533
532
  });
534
533
  } catch (error) {
535
534
  console.log('listenScreenChange的打印error:', error);
536
535
  }
537
536
  });
538
537
  }
539
538
 
540
539
  updateBusinessDomainAndApi(domain, api) {
541
540
  }
542
541
 
543
542
  formatNativeScreenPageData(action) {
544
543
  let getChangePageInfo: any = null;
545
544
  try {
546
545
  const getNativeScreenPageInfoStr = window.XWebView?._callNative(
547
546
  JSON.stringify({
548
547
  plugin: 'JDHybridScreenPlugin',
549
548
  action,
550
549
  sync: '1',
551
550
  }),
552
551
  );
553
552
  const getChangePageInfoData =
554
553
  typeof getNativeScreenPageInfoStr === 'string'
555
554
  ? JSON.parse(getNativeScreenPageInfoStr)
556
555
  : null;
557
556
  if (getChangePageInfoData && typeof getChangePageInfoData === 'object') {
558
557
  const { code, data } = getChangePageInfoData;
559
558
  getChangePageInfo = code && code === '0' ? data : null;
560
559
  }
561
560
  } catch (e) {
562
561
  console.log('JDHybridScreenPlugin转换异常', e);
563
562
  }
564
563
  return getChangePageInfo;
565
564
  }
566
565
 
567
566
  isAndroidFoldScreen() {
568
567
  return this.formatNativeScreenPageData('isFoldScreen') === '1';
569
568
  }
570
569
 
571
570
  isHarmonyFoldScreenPromise(): Promise<{
572
571
  isFoldScreen: boolean;
573
572
  getFoldDisplayMode?: number;
574
573
  }> {
575
574
  return new Promise((resolve) => {
576
575
  this.jmfeReayPromise()
577
576
  .then(() => {
578
577
  if (window.jmfe?.callNative) {
579
578
  Promise.all([
580
579
  window.jmfe.callNative('JDHybridScreenPlugin', 'isFoldScreen', {}),
581
580
  window.jmfe.callNative('JDHybridScreenPlugin', 'getFoldDisplayMode', {}),
582
581
  ])
583
582
  .then((res) => {
584
583
  resolve({
585
584
  isFoldScreen: res?.[0]?.data === '1',
586
585
  getFoldDisplayMode: res?.[1]?.data,
587
586
  });
588
587
  })
589
588
  .catch(() => {
590
589
  resolve({
591
590
  isFoldScreen: false,
592
591
  getFoldDisplayMode: undefined,
593
592
  });
594
593
  });
595
594
  } else {
596
595
  resolve({
597
596
  isFoldScreen: false,
598
597
  getFoldDisplayMode: undefined,
599
598
  });
600
599
  }
601
600
  })
602
601
  .catch(() => {
603
602
  resolve({
604
603
  isFoldScreen: false,
605
604
  getFoldDisplayMode: undefined,
606
605
  });
607
606
  });
608
607
  });
609
608
  }
610
609
 
611
610
  getJdAndroidPageChangeScreenInfo() {
612
611
  const getPageScreenInfo = this.formatNativeScreenPageData('getScreenSize');
613
612
  if (getPageScreenInfo && getPageScreenInfo?.pageWidth && getPageScreenInfo?.pageHeight) {
614
613
  const { pageWidth, pageHeight } = dealNativePixelToCssPixel({
615
614
  pageWidth: getPageScreenInfo.pageWidth,
616
615
  pageHeight: getPageScreenInfo.pageHeight,
617
616
  });
618
617
  getPageScreenInfo.pageWidth = pageWidth;
619
618
  getPageScreenInfo.pageHeight = pageHeight;
620
619
  }
621
620
  return getPageScreenInfo;
622
621
  }
623
622
 
624
623
  getRootEleWindowWidthInfo() {
625
624
  const getRootEleWidth = document.documentElement.getBoundingClientRect().width;
626
625
  const getWindowWidth = window.innerWidth;
627
626
  const getScreenWidth = window.screen.width;
628
627
  return {
629
628
  getRootEleWidth,
630
629
  getWindowWidth,
631
630
  getScreenWidth,
632
631
  };
633
632
  }
634
633
 
635
634
  dealRootEleWidthFn(reportParam = {}, timeout = 0) {
636
635
  const { getRootEleWidth, getWindowWidth, getScreenWidth } = this.getRootEleWindowWidthInfo();
637
636
  console.log(
638
637
  '当前获取根元素的宽度',
639
638
  getRootEleWidth,
640
639
  'getWindowWidth',
641
640
  getWindowWidth,
642
641
  'getScreenWidth',
643
642
  getScreenWidth,
644
643
  );
645
644
  const getLastWidth =
646
645
  getRootEleWidth > 0
647
646
  ? Math.round(getRootEleWidth)
648
647
  : Math.round(getWindowWidth > 0 ? getWindowWidth : getScreenWidth);
649
648
  console.warn(
650
649
  `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果超时,超时时间超时时间${timeout}ms,最终兜底再获取一次根元素宽度${getLastWidth}`,
651
650
  );
652
651
  timeout > 0 &&
653
652
  draBusinessCustomReport({
654
653
  eventName: 'UIInteract',
655
654
  errorName: 'rootEle_width_timeout_getJdScreenSizeInfo',
656
655
  errorMessage: `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果超时,超时时间${timeout}ms,最终兜底再获取一次根元素宽度${getLastWidth}`,
657
656
  extraData: JSON.stringify({
658
657
  isJdApp,
659
658
  getRootEleWidth,
660
659
  getWindowWidth,
661
660
  getScreenWidth,
662
661
  ...reportParam,
663
662
  }),
664
663
  });
665
664
  return getLastWidth;
666
665
  }
667
666
 
668
667
  getPadWindowRootEleWidthPromise() {
669
668
  if (this.rootEleInitWidth > 0) {
670
669
  return Promise.resolve(this.rootEleInitWidth);
671
670
  } else {
672
671
  !this.rootEleWidthRegisterPromise &&
673
672
  (this.rootEleWidthRegisterPromise = new Promise((resolve) => {
674
673
  const getRootEleInitWidth = this.getRootEleWindowWidthInfo().getRootEleWidth;
675
674
  if (getRootEleInitWidth > 0) {
676
675
  console.log('初始化获取根元素宽度正常,为', getRootEleInitWidth);
677
676
  this.rootEleInitWidth = Math.round(getRootEleInitWidth);
678
677
  resolve(this.rootEleInitWidth);
679
678
  } else {
680
679
  const timerPromise = () => {
681
680
  return new Promise((resolve2) => {
682
681
  window.setTimeout(() => {
683
682
  const { getRootEleWidth, getWindowWidth, getScreenWidth } =
684
683
  this.getRootEleWindowWidthInfo();
685
684
  if (getRootEleWidth > 0 || getWindowWidth > 0) {
686
685
  console.warn(
687
686
  `根元素获取宽度初始化为0,200ms后尝试获取最新结果,getRootEleWidth为${getRootEleWidth},getWindowWidth为${getWindowWidth},getScreenWidth为${getScreenWidth}`,
688
687
  );
689
688
  draBusinessCustomReport({
690
689
  eventName: 'UIInteract',
691
690
  errorName: 'rootEle_width_200_timeout_info',
692
691
  errorMessage: `根元素获取宽度初始化为0,200ms后尝试获取最新结果,getRootEleWidth为${getRootEleWidth},getWindowWidth为${getWindowWidth}`,
693
692
  extraData: JSON.stringify({
694
693
  isJdApp,
695
694
  getRootEleWidth,
696
695
  getWindowWidth,
697
696
  getScreenWidth,
698
697
  }),
699
698
  });
700
699
  const getRes =
701
700
  getRootEleWidth > 0 && getWindowWidth > 0
702
701
  ? Math.min(getRootEleWidth, getWindowWidth)
703
702
  : Math.max(getRootEleWidth, getWindowWidth);
704
703
  resolve2({
705
704
  pageWidth: Math.round(getRes),
706
705
  });
707
706
  }
708
707
  }, 200);
709
708
  });
710
709
  };
711
710
  Promise.race([timerPromise(), this.getJdScreenSizeInfoPromise()]).then((res) => {
712
711
  const { pageWidth } = res;
713
712
  console.log('获取结果Promise.race getJdScreenSizeInfo', res);
714
713
  pageWidth > 0 ? resolve(pageWidth) : resolve(this.dealRootEleWidthFn(res, 2000));
715
714
  });
716
715
  }
717
716
  }));
718
717
  return this.rootEleWidthRegisterPromise;
719
718
  }
720
719
  }
721
720
 
722
721
  async getSystemInfo(params) {
723
722
  const getParams = Object.assign({}, params || {});
724
723
  if (this.rootEleInitWidth > 0) {
725
724
  getParams['rootEleInitWidth'] = this.rootEleInitWidth;
726
725
  console.log('获取当前系统信息的时候已经获取到根元素宽度,值为', this.rootEleInitWidth);
727
726
  } else {
728
727
  if (this._getJdPadMinWidthForListen()) {
729
728
  getParams['rootEleInitWidth'] = await this.getPadWindowRootEleWidthPromise();
730
729
  getParams['replaceSystemWidth'] = true;
731
730
  }
732
731
  }
733
732
  isJdApp && this.createLanguagePromise();
734
733
  let info: UtilsInterFace.taroGetSystemInfoSyncRes | any = getSystemInfos(getParams);
735
734
  if (isJdAndAndroidDevice && info?.initWindowWidth <= 0) {
736
735
  let _isfoldScreen = false;
737
736
  const getStorageData = getTaroStorageKeyValue('jd_shopx_androidIsFoldScreen');
738
737
  console.info(
739
738
  '获取当前本地存储是否有jd_shopx_androidIsFoldScreen',
740
739
  getStorageData,
741
740
  '通过缓存值第一次判断是否是折叠屏',
742
741
  getStorageData === 'true',
743
742
  );
744
743
  if (!getStorageData) {
745
744
  _isfoldScreen = this.isAndroidFoldScreen();
746
745
  setTaroStorage('jd_shopx_androidIsFoldScreen', `${_isfoldScreen}`);
747
746
  } else {
748
747
  _isfoldScreen = getStorageData === 'true';
749
748
  }
750
749
  if (_isfoldScreen) {
751
750
  const getJdAndroidPageInfo = this.getJdAndroidPageChangeScreenInfo();
752
751
  if (getJdAndroidPageInfo) {
753
752
  info = getSystemInfos(getJdAndroidPageInfo);
754
753
  console.warn(
755
754
  '当前为松果安卓折叠屏app,获取折叠屏信息',
756
755
  getJdAndroidPageInfo,
757
756
  '获取转换后的系统信息',
758
757
  info,
759
758
  );
760
759
  draBusinessCustomReport({
761
760
  eventName: 'UIInteract',
762
761
  errorName: 'android_jdapp_foldScreen_info',
763
762
  errorMessage:
764
763
  '松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异',
765
764
  extraData: JSON.stringify({
766
765
  title: `松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异`,
767
766
  androidPageInfo: getJdAndroidPageInfo,
768
767
  jdAppVersionStr,
769
768
  taroSysInfo: info,
770
769
  }),
771
770
  });
772
771
  }
773
772
  }
774
773
  }
775
774
  if (isJdApp) {
776
775
  info?.isJdTabletDevice && this.listenJdTabletScreenChange();
777
776
  }
778
777
  this.info.sysInfo = {
779
778
  actualNavBarHeight: 0,
780
779
  ...this.info.sysInfo,
781
780
  ...info,
782
781
  safeContentHeight: info?.screenHeight,
783
782
  headerHeight: 0,
784
783
  tabBarHeight: 0,
785
784
  languageType: languageNowType,
786
785
  };
787
786
  if (isJdApp || isH5AndJingGouMini) {
788
787
  this.getAddressCachePromise();
789
788
  this.getLbsAddressCachePromise();
790
789
  }
791
790
  if (isJdApp) {
792
791
  this.info.sysInfo['hostVersionName'] = jdAppVersionStr;
793
792
  this.info.sysInfo['hostAppVersion'] = jdAppVersion;
794
793
  this.getJdAppBaseInfo();
795
794
  this.getElderModePromise();
796
795
  this.getJDAppearanceStatePromise();
797
796
  this.createJdAndroidRquestEventForTouchStart();
798
797
  }
799
798
  this.getWifiVideoAutoPlayAsync();
800
799
  this.getMPaasConfigAsync();
801
800
  this.getNetWorkType();
802
801
  }
803
802
 
804
803
  getElderModePromise() {
805
804
  if (this.info.sysInfo.hasOwnProperty('jdAppModeType')) {
806
805
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
807
806
  } else {
808
807
  if (isJdAndAndroidDevice) {
809
808
  this.info.sysInfo.jdAppModeType = '0';
810
809
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
811
810
  } else {
812
811
  return Promise.race([
813
812
  this.taskTimeoutPromise(() => {
814
813
  this.info.sysInfo.jdAppModeType = '0';
815
814
  return this.info.sysInfo.jdAppModeType;
816
815
  }),
817
816
  new Promise((resolve) => {
818
817
  const getCallBackName = `getJdCurrentModeType${Date.now()}`;
819
818
  if (!window[getCallBackName]) {
820
819
  window[getCallBackName] = (res) => {
821
820
  try {
822
821
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
823
822
  const { status, data, msg } = getResJson;
824
823
  console.log(`获取松果app展示模式成功,返回结果${data}`);
825
824
  if (status === '0') {
826
825
  this.info.sysInfo.jdAppModeType = data;
827
826
  resolve(data);
828
827
  } else {
829
828
  resolve('0');
830
829
  }
831
830
  } catch (e) {
832
831
  resolve('0');
833
832
  }
834
833
  window[getCallBackName] = null;
835
834
  };
836
835
  }
837
836
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
838
837
  method: 'callSyncRouterModuleWithParams',
839
838
  params: JSON.stringify({
840
839
  routerURL: 'router://JDBModeModule/getCurrentMode',
841
840
  routerParam: {},
842
841
  callBackName: `window.${getCallBackName}`,
843
842
  callBackId: `${getCallBackName}Ios`,
844
843
  }),
845
844
  });
846
845
  }),
847
846
  ]);
848
847
  }
849
848
  }
850
849
  }
851
850
  getAPPUseStraightCorner() {
852
851
  const routerURL = 'router://JDBaseUtilsModule/isUI14Enable';
853
852
  const params = {
854
853
  routerURL,
855
854
  routerParam: {},
856
855
  jdRouter: '1',
857
856
  };
858
857
  if (this.info.sysInfo.hasOwnProperty('jdStraightCorner')) {
859
858
  return Promise.resolve(this.info.sysInfo.jdStraightCorner);
860
859
  } else {
861
860
  return this.jmfeReayPromise()
862
861
  .then(() => {
863
862
  if (isJdAndHarmonyDevice || !isJdApp) {
864
863
  console.log('not APP or is Harmony');
865
864
  return Promise.resolve(false);
866
865
  }
867
866
  console.log('jmfe setShareInfo', params);
868
867
  return Promise.race([
869
868
  window.jmfe.callRouter(params),
870
869
  this.taskTimeoutPromise(() => {
871
870
  return false;
872
871
  }),
873
872
  ]).then(({ status, data }) => {
874
873
  console.log('004 ~ file: index.tsx:133 ~ .then ~ data:', data);
875
874
  console.log('004 ~ file: index.tsx:133 ~ .then ~ status:', status);
876
875
  this.info.sysInfo.jdStraightCorner = status === '0' && Number(data) === 1;
877
876
  return Promise.resolve(status === '0' && Number(data) === 1);
878
877
  });
879
878
  })
880
879
  .catch((e) => {
881
880
  console.log('jmfe error', e);
882
881
  return Promise.resolve(false);
883
882
  });
884
883
  }
885
884
  }
886
885
 
887
886
  getJDAppearanceStatePromise() {
888
887
  if (this.info.sysInfo.hasOwnProperty('jdAppearanceState')) {
889
888
  return Promise.resolve(this.info.sysInfo.jdAppearanceState);
890
889
  } else {
891
890
  return Promise.race([
892
891
  this.taskTimeoutPromise(() => {
893
892
  this.info.sysInfo.jdAppearanceState = '0';
894
893
  return this.info.sysInfo.jdAppearanceState;
895
894
  }),
896
895
  new Promise((resolve) => {
897
896
  const getCallBackName = `getJdCurrentAppearanceState${Date.now()}`;
898
897
  if (!window[getCallBackName]) {
899
898
  window[getCallBackName] = (res) => {
900
899
  try {
901
900
  console.log('getJDAppearanceStatePromise', res);
902
901
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
903
902
  const { status, data, msg } = getResJson;
904
903
  console.log(`获取松果app是否开启黑暗模式成功,返回结果${data}`);
905
904
  if (status === '0') {
906
905
  this.info.sysInfo.jdAppearanceState = data;
907
906
  resolve(data);
908
907
  } else {
909
908
  resolve('0');
910
909
  }
911
910
  } catch (e) {
912
911
  resolve('0');
913
912
  }
914
913
  window[getCallBackName] = null;
915
914
  };
916
915
  }
917
916
  if (isAndroidDevice) {
918
917
  const jsonString = JSON.stringify({
919
918
  callBackName: `window.${getCallBackName}`,
920
919
  });
921
920
  console.log('window.JDAppearance', window?.JDAppearance);
922
921
  window?.JDAppearance &&
923
922
  window?.JDAppearance?.getUiState &&
924
923
  window.JDAppearance.getUiState(jsonString);
925
924
  } else {
926
925
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
927
926
  method: 'callSyncRouterModuleWithParams',
928
927
  params: JSON.stringify({
929
928
  routerURL: 'router://JDWebViewBusinessModule/getJDAppearanceState',
930
929
  routerParam: {},
931
930
  callBackName: `window.${getCallBackName}`,
932
931
  callBackId: `${getCallBackName}Ios`,
933
932
  }),
934
933
  });
935
934
  }
936
935
  }),
937
936
  ]);
938
937
  }
939
938
  }
940
939
 
941
940
  createJdAndroidRquestEventForTouchStart() {
942
941
  if (isJdAndAndroidDevice && window?.JdAndroid) {
943
942
  const rootEleNode = document.querySelector('body');
944
943
  if (rootEleNode) {
945
944
  rootEleNode.addEventListener('touchstart', this.jdAndroidAddEventListenerTouchStart, false);
946
945
  }
947
946
  }
948
947
  }
949
948
  jdAndroidAddEventListenerTouchStart(e) {
950
949
  const isH5SwiperCustomEle = e?.target?.closest('.J_h5SwiperCustom');
951
950
  if (!isH5SwiperCustomEle && window?.JdAndroid) {
952
951
  const hasCustomEle = e
953
952
  ? e?.target?.closest('.J_customScroll') || e?.target?.closest('.J_customLayout')
954
953
  : false;
955
954
  if (!hasCustomEle) {
956
955
  window?.JdAndroid?.requestEvent && window.JdAndroid.requestEvent(false);
957
956
  console.log(
958
957
  'createJdAndroidRquestEvent 所有松果安卓APP内的document touch start事件执行检测requestEvent并重置为false',
959
958
  );
960
959
  }
961
960
  }
962
961
  }
963
962
  removeJdAndroidRquestEventForTouchStart() {
964
963
  if (isJdAndAndroidDevice && window.JdAndroid) {
965
964
  const rootEleNode = document.querySelector('body');
966
965
  if (rootEleNode) {
967
966
  rootEleNode.removeEventListener(
968
967
  'touchstart',
969
968
  this.jdAndroidAddEventListenerTouchStart,
970
969
  false,
971
970
  );
972
971
  }
973
972
  }
974
973
  }
975
974
 
976
975
  getNetWorkType() {
977
976
  if (isJdApp) {
978
977
  return new Promise((resolve) => {
979
978
  this.jmfeReayPromise().then(() => {
980
979
  window.jmfe
981
980
  .getNetworkStatus()
982
981
  .then(({ status, data }) => {
983
982
  console.log('在app内初始化通过jmfe对象获取网络状态完成,当前网络状态====', data);
984
983
  if (status === '0') {
985
984
  this.info.sysInfo['networkType'] = data;
986
985
  resolve({
987
986
  networkType: data,
988
987
  });
989
988
  } else {
990
989
  return this._taroGetNetworkType();
991
990
  }
992
991
  })
993
992
  .catch((err) => {
994
993
  console.log('在app内初始化通过jmfe对象获取网络状态异常====', err);
995
994
  return this._taroGetNetworkType();
996
995
  });
997
996
  });
998
997
  });
999
998
  } else {
1000
999
  return this._taroGetNetworkType();
1001
1000
  }
1002
1001
  }
1003
1002
  _taroGetNetworkType() {
1004
1003
  return Taro.getNetworkType().then((getRes) => {
1005
1004
  if (getRes && getRes.networkType) {
1006
1005
  this.info.sysInfo['netWorkType'] = getRes.networkType;
1007
1006
  console.log(
1008
1007
  '在app内通过taro对象获取网络状态完成,当前网络状态',
1009
1008
  this.info.sysInfo['netWorkType'],
1010
1009
  );
1011
1010
  }
1012
1011
  return getRes;
1013
1012
  });
1014
1013
  }
1015
1014
 
1016
1015
  getJdAppBaseInfo() {
1017
1016
  const appKeyCacheToCookieMinuteTime =
1018
1017
  window?.shopGlobalSwitch?.appKeyCacheToCookieMinuteTime || 0,
1019
1018
  appUuidCacheToCookieMinuteTime =
1020
1019
  window?.shopGlobalSwitch?.appUuidCacheToCookieMinuteTime || 0,
1021
1020
  getAppKey = cookie.get(cacheAppKey),
1022
1021
  getAppUuidKey = cookie.get(cacheAppUuidKey);
1023
1022
  console.log(
1024
1023
  '在app内初始化优先通过cookie获取api请求参数集合baseApiKeyParam',
1025
1024
  cacheAppKey,
1026
1025
  getAppKey,
1027
1026
  cacheAppUuidKey,
1028
1027
  getAppUuidKey,
1029
1028
  );
1030
1029
  if (
1031
1030
  appKeyCacheToCookieMinuteTime &&
1032
1031
  appUuidCacheToCookieMinuteTime &&
1033
1032
  getAppKey &&
1034
1033
  getAppUuidKey
1035
1034
  ) {
1036
1035
  const [uuid, eufv] = getAppUuidKey.split('@');
1037
1036
  const baseApiKeyParam = {
1038
1037
  uuid,
1039
1038
  };
1040
1039
  getAppKey !== '-1000' && (baseApiKeyParam['x_app_key'] = getAppKey);
1041
1040
  if (eufv === '1' && /-/.test(uuid)) {
1042
1041
  const [eu, fv] = uuid.split('-');
1043
1042
  baseApiKeyParam['eu'] = eu;
1044
1043
  baseApiKeyParam['fv'] = fv;
1045
1044
  }
1046
1045
  this.info.sysInfo['baseApiKeyParam'] = baseApiKeyParam;
1047
1046
  this.jmfeReayPromise().then(() => {
1048
1047
  console.log('在app内初始化通过cookie获取api请求参数集合baseApiKeyParam', baseApiKeyParam);
1049
1048
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, baseApiKeyParam);
1050
1049
  });
1051
1050
  } else {
1052
1051
  const checkGetJdAppKeyState =
1053
1052
  window?.shopGlobalSwitch?.getJdAppKeyVersion &&
1054
1053
  jdAppVersionCompare(window?.shopGlobalSwitch?.getJdAppKeyVersion) >= 0;
1055
1054
  this.jmfeReayPromise().then(() => {
1056
1055
  Promise.all([
1057
1056
  checkGetJdAppKeyState && window.jmfe?.callNative
1058
1057
  ? window.jmfe.callNative('SwitchQueryPlugin', 'getAppKey', {}, '0')
1059
1058
  : Promise.resolve({
1060
1059
  status: '-1000',
1061
1060
  msg: '当前版本不支持获取松果app中的getAppKey',
1062
1061
  data: '-1000',
1063
1062
  }),
1064
1063
  window.jmfe.getDeviceInfo(),
1065
1064
  ]).then((resList) => {
1066
1065
  const [getAppKeyRes, deviceInfoRes] = resList;
1067
1066
  console.log(
1068
1067
  '在app内初始化通过jmfe获取getAppKey结果',
1069
1068
  getAppKeyRes,
1070
1069
  '通过jmfe获取getDeviceInfo获取结果',
1071
1070
  deviceInfoRes,
1072
1071
  );
1073
1072
  const baseApiKeyParam = {};
1074
1073
  if (['0', '-1000'].includes(getAppKeyRes?.status) && getAppKeyRes?.data) {
1075
1074
  const getJmfeAppKey = getAppKeyRes?.data;
1076
1075
  if (getJmfeAppKey && getJmfeAppKey !== '') {
1077
1076
  getJmfeAppKey !== '-1000' && (baseApiKeyParam['x_app_key'] = getJmfeAppKey);
1078
1077
  const getJdAppKeyCacheToCookieMinuteTime =
1079
1078
  (window?.shopGlobalSwitch?.appKeyCacheToCookieMinuteTime || 0) * 60 * 1000;
1080
1079
  if (getJdAppKeyCacheToCookieMinuteTime) {
1081
1080
  const expires = new Date(Date.now() + getJdAppKeyCacheToCookieMinuteTime);
1082
1081
  cookie.set(cacheAppKey, getJmfeAppKey, {
1083
1082
  path: '/',
1084
1083
  expires,
1085
1084
  });
1086
1085
  }
1087
1086
  }
1088
1087
  }
1089
1088
  if (deviceInfoRes?.status === '0' && deviceInfoRes?.data) {
1090
1089
  const { uuid, eufv = '0', networkType } = deviceInfoRes?.data;
1091
1090
  if (uuid && uuid !== '') {
1092
1091
  networkType && (this.info.sysInfo['netWorkType'] = networkType);
1093
1092
  baseApiKeyParam['uuid'] = uuid;
1094
1093
  if (eufv === '1' && /-/.test(uuid)) {
1095
1094
  const [eu, fv] = uuid.split('-');
1096
1095
  baseApiKeyParam['eu'] = eu;
1097
1096
  baseApiKeyParam['fv'] = fv;
1098
1097
  }
1099
1098
  const getAppUuidCacheToCookieMinuteTime =
1100
1099
  (window?.shopGlobalSwitch?.appUuidCacheToCookieMinuteTime || 0) * 60 * 1000;
1101
1100
  if (getAppUuidCacheToCookieMinuteTime) {
1102
1101
  const expires = new Date(Date.now() + getAppUuidCacheToCookieMinuteTime);
1103
1102
  cookie.set(cacheAppUuidKey, `${uuid}@${eufv}`, {
1104
1103
  path: '/',
1105
1104
  expires,
1106
1105
  });
1107
1106
  }
1108
1107
  }
1109
1108
  }
1110
1109
  console.log(
1111
1110
  '在app内初始化通过jmfe需要更新的基础api请求参数集合baseApiKeyParam',
1112
1111
  baseApiKeyParam,
1113
1112
  );
1114
1113
  if (Object.keys(baseApiKeyParam).length > 0) {
1115
1114
  this.info.sysInfo['baseApiKeyParam'] = baseApiKeyParam;
1116
1115
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, baseApiKeyParam);
1117
1116
  }
1118
1117
  });
1119
1118
  });
1120
1119
  }
1121
1120
  }
1122
1121
 
1123
1122
  getCacheAddressRouter() {
1124
1123
  if (isJdApp) {
1125
1124
  if (!isJdAndHarmonyDevice) {
1126
1125
  return Promise.race([
1127
1126
  new Promise((resolve) => {
1128
1127
  const getCallBackName = `getJdCacheAddress${Date.now()}`;
1129
1128
  if (!window[getCallBackName]) {
1130
1129
  window[getCallBackName] = (res) => {
1131
1130
  console.warn(`获取松果appGetJdCacheAddressRes,返回结果`, res);
1132
1131
  try {
1133
1132
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
1134
1133
  resolve(getResJson);
1135
1134
  } catch (e) {
1136
1135
  resolve({
1137
1136
  status: '-1002',
1138
1137
  msg: '地址信息解析json异常',
1139
1138
  res,
1140
1139
  });
1141
1140
  }
1142
1141
  window[getCallBackName] = null;
1143
1142
  };
1144
1143
  }
1145
1144
  const getRouterParam = {
1146
1145
  sceneId: 'basicShoppingProcess',
1147
1146
  };
1148
1147
  if (isAndroidDevice) {
1149
1148
  return callRouterAndroid({
1150
1149
  routerURL: 'router://JDAddressModule/getCacheAddress',
1151
1150
  routerParam: getRouterParam,
1152
1151
  callBackName: getCallBackName,
1153
1152
  isSync: true,
1154
1153
  });
1155
1154
  } else {
1156
1155
  return callRouterIOS({
1157
1156
  routerURL: 'router://JDBAddressCacheManagerModule/getCacheAddress',
1158
1157
  routerParam: getRouterParam,
1159
1158
  callBackName: getCallBackName,
1160
1159
  });
1161
1160
  }
1162
1161
  }),
1163
1162
  this.taskTimeoutPromise(() => {
1164
1163
  return {
1165
1164
  status: '-1000',
1166
1165
  msg: '原生router协议获取地址信息超时',
1167
1166
  };
1168
1167
  }, 3000),
1169
1168
  ]);
1170
1169
  } else {
1171
1170
  return Promise.race([
1172
1171
  new Promise((resolve) => {
1173
1172
  this.jmfeReayPromise()
1174
1173
  .then(() => {
1175
1174
  const plugin = 'JDHybridRouterPlugin';
1176
1175
  const action = 'callSyncRouterModuleWithParams';
1177
1176
  const params = {
1178
1177
  routerURL: 'router://JDAddressCacheModule/getAddressCache?sceneId=1',
1179
1178
  routerParam: '',
1180
1179
  };
1181
1180
  const sync = '1';
1182
1181
  try {
1183
1182
  window.jmfe.callNative(plugin, action, params, sync).then((res) => {
1184
1183
  resolve(res);
1185
1184
  });
1186
1185
  } catch (error) {
1187
1186
  resolve({
1188
1187
  status: '-1001',
1189
1188
  msg: '判断jmfe不存在,获取经纬度信息异常',
1190
1189
  });
1191
1190
  }
1192
1191
  })
1193
1192
  .catch(() => {
1194
1193
  resolve({
1195
1194
  status: '-1002',
1196
1195
  msg: '鸿蒙系统调用jmfe异常,获取失败',
1197
1196
  });
1198
1197
  });
1199
1198
  }),
1200
1199
  this.taskTimeoutPromise(() => {
1201
1200
  return {
1202
1201
  status: '-1000',
1203
1202
  msg: '原生router协议获取地址信息超时',
1204
1203
  };
1205
1204
  }, 3000),
1206
1205
  ]);
1207
1206
  }
1208
1207
  } else if (isH5AndJingGouMini) {
1209
1208
  const { areaId, addressName } = this.getJingGouMiniInh5Address();
1210
1209
  if (areaId && areaId !== '' && addressName && addressName !== '') {
1211
1210
  return Promise.resolve({
1212
1211
  status: '0',
1213
1212
  data: {
1214
1213
  areaId,
1215
1214
  fullAddress: addressName,
1216
1215
  },
1217
1216
  });
1218
1217
  } else {
1219
1218
  return Promise.resolve({
1220
1219
  status: '-1002',
1221
1220
  msg: '京购内嵌h5h5暂无业务需要,未实现,获取失败',
1222
1221
  });
1223
1222
  }
1224
1223
  } else {
1225
1224
  return Promise.resolve({
1226
1225
  status: '-1002',
1227
1226
  msg: '普通h5暂无业务需要,未实现,获取失败',
1228
1227
  });
1229
1228
  }
1230
1229
  }
1231
1230
 
1232
1231
  getJingGouMiniInh5Address() {
1233
1232
  let getRes: any = {
1234
1233
  areaId: '',
1235
1234
  addressName: '',
1236
1235
  };
1237
1236
  try {
1238
1237
  const getUrlHast = decodeURIComponent(window.location.hash || '');
1239
1238
  const sensMatch = getUrlHast ? getUrlHast.match(/sens=({.*?})/) : null;
1240
1239
  if (sensMatch && sensMatch[1]) {
1241
1240
  const sensData = JSON.parse(sensMatch[1]);
1242
1241
  const getWqAddr = sensData?.wq_addr || '';
1243
1242
  if (getWqAddr && /\|/.test(getWqAddr)) {
1244
1243
  const addressList = getWqAddr.split(/\|/);
1245
1244
  const [addressId, areaId, areaName, addressName, coordinate] = addressList;
1246
1245
  getRes = {
1247
1246
  addressId,
1248
1247
  areaId,
1249
1248
  areaName,
1250
1249
  addressName,
1251
1250
  coordinate,
1252
1251
  };
1253
1252
  }
1254
1253
  }
1255
1254
  } catch (e) {
1256
1255
  console.log('获取hash转换异常', e);
1257
1256
  }
1258
1257
  return getRes;
1259
1258
  }
1260
1259
 
1261
1260
  getAddressCachePromise() {
1262
1261
  return new Promise((resolve) => {
1263
1262
  if (this?.info?.sysInfo?.lat && this?.info?.sysInfo?.lng && this?.info?.sysInfo?.area) {
1264
1263
  resolve({
1265
1264
  lat: this.info.sysInfo.lat,
1266
1265
  lng: this.info.sysInfo.lng,
1267
1266
  area: this?.info?.sysInfo?.area,
1268
1267
  fullAddress: this?.info?.pageInfo?.fullAddress,
1269
1268
  });
1270
1269
  } else {
1271
1270
  this.getCacheAddressRouter()
1272
1271
  .then((res) => {
1273
1272
  const { status, data } = res;
1274
1273
  console.log('原生端获取经纬度及四级地址原始数据结果', status, data, res);
1275
1274
  if (status === '0' && data) {
1276
1275
  const {
1277
1276
  lat,
1278
1277
  latitude,
1279
1278
  lng,
1280
1279
  longitude,
1281
1280
  provinceId,
1282
1281
  cityId,
1283
1282
  countyId,
1284
1283
  townId,
1285
1284
  fullAddress,
1286
1285
  areaId,
1287
1286
  } = data || {};
1288
1287
  const getAreaIdsEnable = areaId && areaId !== '';
1289
1288
  const getEncodeFullAddress = fullAddress ? encodeURIComponent(fullAddress) : '';
1290
1289
  let area = getAreaIdsEnable ? areaId : '';
1291
1290
  this.info.sysInfo['lat'] = `${lat || latitude || ''}`;
1292
1291
  this.info.sysInfo['lng'] = `${lng || longitude || ''}`;
1293
1292
  const getProvinceIdNum = provinceId ? Number(provinceId) : 0;
1294
1293
  if ((getProvinceIdNum && getProvinceIdNum > 0) || getAreaIdsEnable) {
1295
1294
  area = getAreaIdsEnable
1296
1295
  ? areaId
1297
1296
  : `${provinceId}_${cityId || 0}_${countyId || 0}_${townId || 0}`;
1298
1297
  this.info.pageInfo['address'] = area;
1299
1298
  this.info.pageInfo['addressCommaStr'] = area.replace(/_/g, ',');
1300
1299
  this.info.sysInfo['area'] = area;
1301
1300
  const getUpdateData = {
1302
1301
  area: this.info.pageInfo.address,
1303
1302
  };
1304
1303
  if (fullAddress && fullAddress.length > 0) {
1305
1304
  getUpdateData['fullAddress'] = getEncodeFullAddress;
1306
1305
  this.info.pageInfo['fullAddress'] = getEncodeFullAddress;
1307
1306
  }
1308
1307
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, getUpdateData);
1309
1308
  }
1310
1309
  resolve({
1311
1310
  lat: this.info.sysInfo['lat'],
1312
1311
  lng: this.info.sysInfo['lng'],
1313
1312
  fullAddress: getEncodeFullAddress,
1314
1313
  area: area,
1315
1314
  });
1316
1315
  } else {
1317
1316
  if (typeof res === 'object') {
1318
1317
  draBusinessCustomReport({
1319
1318
  eventName: 'business',
1320
1319
  errorName: 'jdapp_getCacheAddress_info_err',
1321
1320
  errorMessage: '松果app内通过router协议获取用户地址及经纬度信息异常',
1322
1321
  extraData: JSON.stringify({
1323
1322
  isJdApp,
1324
1323
  jdAppVersion: jdAppVersionStr,
1325
1324
  ...res,
1326
1325
  }),
1327
1326
  });
1328
1327
  }
1329
1328
  resolve({ lat: '', lng: '', area: '', fullAddress: '' });
1330
1329
  }
1331
1330
  })
1332
1331
  .catch((e) => {
1333
1332
  console.log('getCacheAddressRouter catch e,获取经纬度信息异常e', e);
1334
1333
  draBusinessCustomReport({
1335
1334
  eventName: 'business',
1336
1335
  errorName: 'jdapp_getCacheAddress_info_catch_err',
1337
1336
  errorMessage: '松果app内通过router协议获取用户地址及经纬度信息catch异常',
1338
1337
  extraData: JSON.stringify({
1339
1338
  isJdApp,
1340
1339
  jdAppVersion: jdAppVersionStr,
1341
1340
  }),
1342
1341
  });
1343
1342
  resolve({ lat: '', lng: '', area: '', fullAddress: '' });
1344
1343
  });
1345
1344
  }
1346
1345
  });
1347
1346
  }
1348
1347
 
1349
1348
  getLbsCacheAddressRouter() {
1350
1349
  if (isJdApp) {
1351
1350
  if (!isJdAndHarmonyDevice) {
1352
1351
  return Promise.race([
1353
1352
  new Promise((resolve) => {
1354
1353
  const getCallBackName = `getJdLbsCacheAddress${Date.now()}`;
1355
1354
  if (!window[getCallBackName]) {
1356
1355
  window[getCallBackName] = (res) => {
1357
1356
  console.warn(`获取松果appGetJdLbsCacheAddressRes,返回结果`, res);
1358
1357
  try {
1359
1358
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
1360
1359
  resolve(getResJson);
1361
1360
  } catch (e) {
1362
1361
  resolve({
1363
1362
  status: '-1002',
1364
1363
  msg: '地址信息解析json异常',
1365
1364
  res,
1366
1365
  });
1367
1366
  }
1368
1367
  window[getCallBackName] = null;
1369
1368
  };
1370
1369
  }
1371
1370
  const getRouterParam = {
1372
1371
  appid: '219f70bbbf7e4ede7968bedaa1beafb4',
1373
1372
  sceneId: 'basicShoppingProcess',
1374
1373
  };
1375
1374
  if (isAndroidDevice) {
1376
1375
  return callRouterAndroid({
1377
1376
  routerURL: 'router://com.jingdong.app.mall.location.JSLocationManager/getLocation',
1378
1377
  routerParam: getRouterParam,
1379
1378
  callBackName: getCallBackName,
1380
1379
  isSync: true,
1381
1380
  hasJdRouter: false,
1382
1381
  });
1383
1382
  } else {
1384
1383
  return callRouterIOS({
1385
1384
  routerURL: 'router://JDBLBSKitModule/getCacheAddressInfo',
1386
1385
  routerParam: getRouterParam,
1387
1386
  callBackName: getCallBackName,
1388
1387
  isSync: true,
1389
1388
  });
1390
1389
  }
1391
1390
  }),
1392
1391
  this.taskTimeoutPromise(() => {
1393
1392
  return {
1394
1393
  status: '-1000',
1395
1394
  msg: '原生router协议获取lbs地址信息3s超时',
1396
1395
  };
1397
1396
  }, 3000),
1398
1397
  ]);
1399
1398
  } else {
1400
1399
  return Promise.resolve({
1401
1400
  status: '-1001',
1402
1401
  msg: '鸿蒙系统调用未实现,获取失败',
1403
1402
  });
1404
1403
  }
1405
1404
  } else if (isH5AndJingGouMini) {
1406
1405
  return this.getLocationForGpsPromise();
1407
1406
  } else {
1408
1407
  return Promise.resolve({
1409
1408
  status: '-1002',
1410
1409
  msg: '普通h5暂无业务需要,未实现,获取失败',
1411
1410
  });
1412
1411
  }
1413
1412
  }
1414
1413
  getLocationForGpsPromise() {
1415
1414
  return new Promise((resolve) => {
1416
1415
  let hasGetLocationForGps = true;
1417
1416
  if (urlCookie && urlCookie['loc']) {
1418
1417
  const [provinceid = 0, cityid = 0, districtid = 0, townid = 0] =
1419
1418
  urlCookie['loc'].split('_');
1420
1419
  const getProvinceIdNum = provinceid ? Number(provinceid) : 0;
1421
1420
  if (getProvinceIdNum && getProvinceIdNum > 0) {
1422
1421
  hasGetLocationForGps = false;
1423
1422
  resolve({
1424
1423
  status: '0',
1425
1424
  data: {
1426
1425
  provinceid,
1427
1426
  cityid,
1428
1427
  districtid,
1429
1428
  townid,
1430
1429
  origin: 'wxapp',
1431
1430
  },
1432
1431
  });
1433
1432
  }
1434
1433
  }
1435
1434
  if (hasGetLocationForGps && window?.navigator?.geolocation) {
1436
1435
  window.navigator.geolocation.getCurrentPosition(
1437
1436
  (position) => {
1438
1437
  console.log('h5 浏览器通过原生geolocation获取经纬度结果', position?.coords);
1439
1438
  if (position?.coords) {
1440
1439
  resolve({
1441
1440
  status: '0',
1442
1441
  data: {
1443
1442
  srclat: position.coords?.latitude,
1444
1443
  srclng: position.coords.longitude,
1445
1444
  origin: 'h5',
1446
1445
  },
1447
1446
  });
1448
1447
  } else {
1449
1448
  resolve({
1450
1449
  status: '-1001',
1451
1450
  msg: 'h5 浏览器通过原生geolocation获取经纬度结果异常,详情见position',
1452
1451
  position,
1453
1452
  });
1454
1453
  }
1455
1454
  },
1456
1455
  (error) => {
1457
1456
  resolve({
1458
1457
  status: '-1001',
1459
1458
  msg: 'h5 浏览器通过原生geolocation获取经纬度结果定位异常,详情见error',
1460
1459
  error,
1461
1460
  });
1462
1461
  },
1463
1462
  {
1464
1463
  enableHighAccuracy: false,
1465
1464
  timeout: 3 * 1000,
1466
1465
  maximumAge: 10 * 60 * 1000,
1467
1466
  },
1468
1467
  );
1469
1468
  } else {
1470
1469
  resolve({
1471
1470
  status: '-1001',
1472
1471
  msg: '您的浏览器不支持地理定位',
1473
1472
  });
1474
1473
  }
1475
1474
  });
1476
1475
  }
1477
1476
 
1478
1477
  createLbsCacheAddress(realTimeArea) {
1479
1478
  const getLbsAddressCacheMinuteTime = Number(
1480
1479
  window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime || 0,
1481
1480
  );
1482
1481
  console.log(
1483
1482
  '获取lbs缓存到cookie的时间,分钟',
1484
1483
  getLbsAddressCacheMinuteTime,
1485
1484
  'lbsAddressCacheToCookieMinuteTime',
1486
1485
  window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime,
1487
1486
  );
1488
1487
  if (getLbsAddressCacheMinuteTime > 0) {
1489
1488
  const expires = new Date(Date.now() + getLbsAddressCacheMinuteTime * 60 * 1000);
1490
1489
  realTimeArea &&
1491
1490
  cookie.set(cacheH5LbsAddressKey, realTimeArea, {
1492
1491
  path: '/',
1493
1492
  expires,
1494
1493
  });
1495
1494
  }
1496
1495
  }
1497
1496
 
1498
1497
  getLbsAddressCachePromise() {
1499
1498
  if (!this.lbsAddressCachePromise) {
1500
1499
  this.lbsAddressCachePromise = new Promise((resolve) => {
1501
1500
  const getCookieForLbsAddress = window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime
1502
1501
  ? cookie.get(cacheH5LbsAddressKey)
1503
1502
  : '';
1504
1503
  const getUserLbsAddress = this?.info?.pageInfo?.userLbsAddress;
1505
1504
  if (getUserLbsAddress && getUserLbsAddress !== '') {
1506
1505
  resolve({
1507
1506
  ok: true,
1508
1507
  realTimeArea: getUserLbsAddress,
1509
1508
  });
1510
1509
  } else if (getCookieForLbsAddress && getCookieForLbsAddress !== '') {
1511
1510
  console.info(
1512
1511
  `通过cookie获取缓存的userLbsAddress,${window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime}分钟内有效`,
1513
1512
  getCookieForLbsAddress,
1514
1513
  );
1515
1514
  this.info.pageInfo['userLbsAddress'] = getCookieForLbsAddress;
1516
1515
  this.info.sysInfo['realTimeArea'] = getCookieForLbsAddress;
1517
1516
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, {
1518
1517
  realTimeArea: getCookieForLbsAddress,
1519
1518
  });
1520
1519
  resolve({
1521
1520
  ok: true,
1522
1521
  realTimeArea: getCookieForLbsAddress,
1523
1522
  });
1524
1523
  } else {
1525
1524
  this.getLbsCacheAddressRouter()
1526
1525
  .then((res) => {
1527
1526
  const { status, data } = res;
1528
1527
  console.log(
1529
1528
  '原生或者内嵌京购端获取基于lbs的经纬度及四级地址原始数据结果',
1530
1529
  status,
1531
1530
  data,
1532
1531
  res,
1533
1532
  );
1534
1533
  if (status === '0' && data) {
1535
1534
  const { srclat, srclng, provinceid, cityid, districtid, townid, origin } =
1536
1535
  data || {};
1537
1536
  let realTimeArea = '';
1538
1537
  this.info.sysInfo['srclat'] = `${srclat || ''}`;
1539
1538
  this.info.sysInfo['srclng'] = `${srclng || ''}`;
1540
1539
  const getProvinceIdNum = provinceid ? Number(provinceid) : 0;
1541
1540
  if (getProvinceIdNum && getProvinceIdNum > 0) {
1542
1541
  realTimeArea = `${provinceid}_${cityid || 0}_${districtid || 0}_${townid || 0}`;
1543
1542
  this.info.pageInfo['userLbsAddress'] = realTimeArea;
1544
1543
  this.info.sysInfo['realTimeArea'] = realTimeArea;
1545
1544
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, {
1546
1545
  realTimeArea: this.info.pageInfo.userLbsAddress,
1547
1546
  });
1548
1547
  this.createLbsCacheAddress(realTimeArea);
1549
1548
  } else {
1550
1549
  !origin && (this.lbsAddressCachePromise = null);
1551
1550
  }
1552
1551
  const getValidRealTimeArea = realTimeArea !== '';
1553
1552
  resolve({
1554
1553
  lat: this.info.sysInfo['srclat'],
1555
1554
  lng: this.info.sysInfo['srclng'],
1556
1555
  realTimeArea: realTimeArea,
1557
1556
  ok: getValidRealTimeArea,
1558
1557
  msg: getValidRealTimeArea
1559
1558
  ? '成功'
1560
1559
  : origin
1561
1560
  ? origin
1562
1561
  : '根据router底层获取lbs地址信息异常,详情见data',
1563
1562
  data: getValidRealTimeArea ? null : res,
1564
1563
  });
1565
1564
  if (!getValidRealTimeArea && !origin) {
1566
1565
  draBusinessCustomReport({
1567
1566
  eventName: 'business',
1568
1567
  errorName: 'h5_getLbsCacheAddress_info_err',
1569
1568
  errorMessage:
1570
1569
  '松果app内通过router协议获取基于lbs实时用户地址及经纬度信息catch异常',
1571
1570
  extraData: JSON.stringify({
1572
1571
  isJdApp,
1573
1572
  jdAppVersion: jdAppVersionStr,
1574
1573
  }),
1575
1574
  });
1576
1575
  }
1577
1576
  } else {
1578
1577
  typeof res === 'object' &&
1579
1578
  draBusinessCustomReport({
1580
1579
  eventName: 'business',
1581
1580
  errorName: 'h5_getLbsCacheAddress_info_err',
1582
1581
  errorMessage:
1583
1582
  'h5通过router协议或者浏览器gps获取基于lbs实时用户缓存地址及经纬度信息异常',
1584
1583
  extraData: JSON.stringify({
1585
1584
  isJdApp,
1586
1585
  jdAppVersion: jdAppVersionStr,
1587
1586
  ...res,
1588
1587
  }),
1589
1588
  });
1590
1589
  this.lbsAddressCachePromise = null;
1591
1590
  resolve({ realTimeArea: '', ok: false });
1592
1591
  }
1593
1592
  })
1594
1593
  .catch((e) => {
1595
1594
  console.log('getLbsAddressCachePromise catch e,获取经纬度信息异常e', e);
1596
1595
  this.lbsAddressCachePromise = null;
1597
1596
  draBusinessCustomReport({
1598
1597
  eventName: 'business',
1599
1598
  errorName: 'h5_getLbsCacheAddress_info_err',
1600
1599
  errorMessage:
1601
1600
  'h5内通过router协议获取浏览器gps获取基于lbs实时用户地址及经纬度信息catch异常',
1602
1601
  extraData: JSON.stringify({
1603
1602
  isJdApp,
1604
1603
  jdAppVersion: jdAppVersionStr,
1605
1604
  }),
1606
1605
  });
1607
1606
  resolve({ realTimeArea: '', ok: false });
1608
1607
  });
1609
1608
  }
1610
1609
  });
1611
1610
  }
1612
1611
  return this.lbsAddressCachePromise;
1613
1612
  }
1614
1613
 
1615
1614
  async updateMPaasConfigAsync(isBeforePageReady: boolean) {
1616
1615
  console.log('updateMPaasConfigAsync isBeforePageReady:', isBeforePageReady);
1617
1616
  if (!isJdApp) {
1618
1617
  return;
1619
1618
  }
1620
1619
  const avifSwitch = await getMPaasConfigByBussinessKey('avifSwitch', isBeforePageReady);
1621
1620
  this.info.sysInfo.dynamicConfig['avifSwitch'] = avifSwitch;
1622
1621
  const hybridHttpSwitch = await getMPaasConfigByBussinessKey(
1623
1622
  'hybridHttpSwitch',
1624
1623
  isBeforePageReady,
1625
1624
  );
1626
1625
  const jshopIsVipShopSwitch = await getMPaasConfigByBussinessKey(
1627
1626
  'jshopIsVipShop',
1628
1627
  isBeforePageReady,
1629
1628
  );
1630
1629
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = hybridHttpSwitch;
1631
1630
  this.info.sysInfo.dynamicConfig['jshopIsVipShopSwitch'] = jshopIsVipShopSwitch;
1632
1631
  const isFollowAppVideoPlayStatus = await getMPaasConfigByBussinessKey(
1633
1632
  'isFollowAppVideoPlayStatus',
1634
1633
  isBeforePageReady,
1635
1634
  );
1636
1635
  console.log(
1637
1636
  'isBeforePageReady:',
1638
1637
  isBeforePageReady,
1639
1638
  'isFollowAppVideoPlayStatus:',
1640
1639
  isFollowAppVideoPlayStatus,
1641
1640
  );
1642
1641
  if (isFollowAppVideoPlayStatus === true || isFollowAppVideoPlayStatus === 'true') {
1643
1642
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = true;
1644
1643
  }
1645
1644
  }
1646
1645
 
1647
1646
  async getWifiVideoAutoPlayAsync() {
1648
1647
  this.info.sysInfo['wifiVideoAutoPlay'] = false;
1649
1648
  if (!isJdApp) {
1650
1649
  return;
1651
1650
  }
1652
1651
  const videoPlayStatus = await getWifiVideoAutoPlay().catch((e) => {
1653
1652
  return 0;
1654
1653
  });
1655
1654
  if (Number(videoPlayStatus) === 1) {
1656
1655
  this.info.sysInfo['wifiVideoAutoPlay'] = true;
1657
1656
  }
1658
1657
  }
1659
1658
 
1660
1659
  async getMPaasConfigAsync() {
1661
1660
  this.info.sysInfo.dynamicConfig = {};
1662
1661
  this.info.sysInfo.dynamicConfig['avifSwitch'] = {};
1663
1662
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = {};
1664
1663
  this.info.sysInfo.dynamicConfig['jshopIsVipShopSwitch'] = {};
1665
1664
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = false;
1666
1665
  return this.updateMPaasConfigAsync(true);
1667
1666
  }
1668
1667
 
1669
1668
  getDynamicConfig(key: string) {
1670
1669
  return this.info.sysInfo?.dynamicConfig?.[key];
1671
1670
  }
1672
1671
  async updateMPaasConfig() {
1673
1672
  console.log('updateMPaasConfig');
1674
1673
  if (
1675
1674
  isIosDevice &&
1676
1675
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_VERSION) < 0 &&
1677
1676
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_LOW_VERSION) >= 0
1678
1677
  ) {
1679
1678
  try {
1680
1679
  await this.updateMPaasConfigAsync(false);
1681
1680
  } catch (e) {
1682
1681
  console.log('updateMPaasConfigAsync:', e);
1683
1682
  }
1684
1683
  }
1685
1684
  }
1686
1685
 
1687
1686
  toLogin(options) {
1688
1687
  if (isAscfApp) {
1689
1688
  return this.toAscfAppLogin(options);
1690
1689
  }
1691
1690
  return this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState
1692
1691
  ? this.toWxAppLogin(options)
1693
1692
  : this.toWebLogin(options);
1694
1693
  }
1695
1694
 
1696
1695
  doLogin(options) {
1697
1696
  return this.toLogin(options);
1698
1697
  }
1699
1698
 
1700
1699
  doLoginForJdPin(options = {}) {
1701
1700
  return this.doLogin({
1702
1701
  loginColor: {
1703
1702
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
1704
1703
  dpin: 0,
1705
1704
  },
1706
1705
  ...options,
1707
1706
  });
1708
1707
  }
1709
1708
 
1710
1709
  toWebLogin(options) {
1711
1710
  let params: {
1712
1711
  returnurl: string;
1713
1712
  } = {
1714
1713
  returnurl: '',
1715
1714
  };
1716
1715
  const checkToPcLogin = options ? options?.isPc : isPc;
1717
1716
  const loginUrl = checkToPcLogin
1718
1717
  ? `//passport.jd.com/new/login.aspx`
1719
1718
  : `${domain.mobileLogin}/user/login.action`;
1720
1719
  const defaultParams = {
1721
1720
  appid: /\.jd\.hk/.test(window.location.hostname) ? '233' : '100',
1722
1721
  returnurl: window.location.href,
1723
1722
  };
1724
1723
  if (isString(options)) {
1725
1724
  params = Object.assign({}, defaultParams, {
1726
1725
  returnurl: options,
1727
1726
  });
1728
1727
  } else if (isObject(options)) {
1729
1728
  const { loginColor, ...otherOptions } = options;
1730
1729
  params = Object.assign({}, defaultParams, otherOptions);
1731
1730
  } else {
1732
1731
  params = defaultParams;
1733
1732
  }
1734
1733
  params.returnurl = encodeURIComponent(params.returnurl);
1735
1734
  let getFullUrl = loginUrl + '?' + serialize(params);
1736
1735
  if (checkToPcLogin) {
1737
1736
  getFullUrl = getFullUrl.replace(/returnurl/, 'ReturnUrl');
1738
1737
  }
1739
1738
  return Promise.resolve({
1740
1739
  h5ToUrl: true,
1741
1740
  url: getFullUrl,
1742
1741
  }).then(() => {
1743
1742
  window.location.href = getFullUrl;
1744
1743
  });
1745
1744
  }
1746
1745
 
1747
1746
  toAscfAppLogin(options = {}) {
1748
1747
  console.log('华为元服务中h5登录跳转', options);
1749
1748
  return Promise.resolve(true).then(() => {
1750
1749
  const returnPage = encodeURIComponent(window.location.href);
1751
1750
  if (has && has.ascfweb) {
1752
1751
  has.ascfweb.redirectTo({
1753
1752
  url: `/pages/login/index/index?isH5=1&returnPage=${returnPage}&pageType=h5&source=shopx`,
1754
1753
  });
1755
1754
  }
1756
1755
  });
1757
1756
  }
1758
1757
 
1759
1758
  toWxAppLogin(options = {}) {
1760
1759
  console.log('微信京购小程序中h5登录跳转', options);
1761
1760
  return Promise.resolve(true).then(() => {
1762
1761
  const { loginColor } = Object.assign(
1763
1762
  {},
1764
1763
  {
1765
1764
  loginColor: {
1766
1765
  biz: WXAPP_BIZ_KEY,
1767
1766
  dpin: 1,
1768
1767
  },
1769
1768
  },
1770
1769
  options,
1771
1770
  );
1772
1771
  window.location.href = `${domain.wq}/pinbind/pintokenredirect?biz=${
1773
1772
  loginColor.biz
1774
1773
  }&url=${encodeURIComponent(window.location.href)}`;
1775
1774
  });
1776
1775
  }
1777
1776
 
1778
1777
  getLoginCookie() {
1779
1778
  return Promise.resolve({
1780
1779
  pin: cookie.get('pin') || '',
1781
1780
  });
1782
1781
  }
1783
1782
 
1784
1783
  clearLoginCookie() {
1785
1784
  cookie.remove('pin');
1786
1785
  }
1787
1786
 
1788
1787
  checkStatusAndLogin(options = {}) {
1789
1788
  if (!this.checkStatusAndLoginPromise) {
1790
1789
  this.checkStatusAndLoginPromise = new Promise(async (resolve, reject) => {
1791
1790
  try {
1792
1791
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
1793
1792
  if (getLoginState) {
1794
1793
  resolve(true);
1795
1794
  } else {
1796
1795
  this.toLogin(options);
1797
1796
  reject(false);
1798
1797
  }
1799
1798
  } catch (e) {
1800
1799
  this.toLogin(options);
1801
1800
  reject(false);
1802
1801
  }
1803
1802
  });
1804
1803
  return this.checkStatusAndLoginPromise;
1805
1804
  } else {
1806
1805
  return this.checkStatusAndLoginPromise
1807
1806
  .then(() => {
1808
1807
  return Promise.resolve(true);
1809
1808
  })
1810
1809
  .catch(() => {
1811
1810
  this.toLogin(options);
1812
1811
  return Promise.reject(true);
1813
1812
  });
1814
1813
  }
1815
1814
  }
1816
1815
 
1817
1816
  checkJdStatusAndLogin(
1818
1817
  options = {
1819
1818
  loginColor: {
1820
1819
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
1821
1820
  dpin: 0,
1822
1821
  },
1823
1822
  },
1824
1823
  ) {
1825
1824
  return this.checkStatusAndLogin(options);
1826
1825
  }
1827
1826
 
1828
1827
  doCheckLoginStateAndForApiCheck(options) {
1829
1828
  if (this.info.loginState) {
1830
1829
  return Promise.resolve(true);
1831
1830
  } else {
1832
1831
  return new Promise((resolve, reject) => {
1833
1832
  if (this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState) {
1834
1833
  const getWqAuthToken = cookie.get('wq_auth_token');
1835
1834
  const getWqSkey = cookie.get('wq_skey');
1836
1835
  const getWqUin = cookie.get('wq_uin');
1837
1836
  const isLoginState =
1838
1837
  options?.loginColor?.dpin === 0 ? getWqAuthToken : getWqSkey && getWqUin;
1839
1838
  if (isLoginState) {
1840
1839
  this.info.loginState = true;
1841
1840
  resolve(true);
1842
1841
  } else {
1843
1842
  reject(false);
1844
1843
  }
1845
1844
  } else {
1846
1845
  Taro.request({
1847
1846
  url: api.isLogin,
1848
1847
  jsonp: true,
1849
1848
  timeout: 3000,
1850
1849
  success: (res) => {
1851
1850
  const { statusCode, data } = res;
1852
1851
  if (statusCode === 200 && data?.islogin && Number(data.islogin) === 1) {
1853
1852
  this.info.loginState = true;
1854
1853
  resolve(true);
1855
1854
  } else {
1856
1855
  reject(false);
1857
1856
  }
1858
1857
  },
1859
1858
  fail: (err) => {
1860
1859
  console.log('登录检查异常', err);
1861
1860
  reject(false);
1862
1861
  },
1863
1862
  });
1864
1863
  }
1865
1864
  });
1866
1865
  }
1867
1866
  }
1868
1867
 
1869
1868
  checkLoginStatus(options) {
1870
1869
  return new Promise(async (resolve, reject) => {
1871
1870
  try {
1872
1871
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
1873
1872
  if (getLoginState) {
1874
1873
  const { pin } = await this.getLoginCookie();
1875
1874
  this.info.userInfo = {
1876
1875
  pin,
1877
1876
  encodePin: encodeURIComponent(pin),
1878
1877
  ptkey: '',
1879
1878
  };
1880
1879
  resolve(true);
1881
1880
  } else {
1882
1881
  reject(false);
1883
1882
  }
1884
1883
  } catch (e) {
1885
1884
  reject(false);
1886
1885
  }
1887
1886
  });
1888
1887
  }
1889
1888
 
1890
1889
  updatePageAndLogInfo(updateQuery = {}) {
1891
1890
  const createUpdateQueryInfo: {
1892
1891
  query: {
1893
1892
  shopId?: string | number;
1894
1893
  venderId?: string | number;
1895
1894
  };
1896
1895
  updateShopInfoState: boolean;
1897
1896
  } = Object.assign(
1898
1897
  {},
1899
1898
  {
1900
1899
  query: {},
1901
1900
  updateShopInfoState: false,
1902
1901
  },
1903
1902
  updateQuery,
1904
1903
  );
1905
1904
  console.log(
1906
1905
  '获取当前下发的店铺查询参数',
1907
1906
  updateQuery,
1908
1907
  '获取之前保存的shopInfo店铺查询参数',
1909
1908
  this.info?.shopInfo,
1910
1909
  );
1911
1910
  const { query, updateShopInfoState } = createUpdateQueryInfo;
1912
1911
  const { shopId, venderId, un_area } = query;
1913
1912
  if (updateShopInfoState) {
1914
1913
  this.info.queryInfo = {
1915
1914
  ...this.info.queryInfo,
1916
1915
  ...query,
1917
1916
  };
1918
1917
  if (shopId && venderId) {
1919
1918
  this.info.shopInfo = {
1920
1919
  shopId: `${shopId}`,
1921
1920
  venderId: `${venderId}`,
1922
1921
  };
1923
1922
  }
1924
1923
  } else {
1925
1924
  this.info.queryInfo = {
1926
1925
  ...query,
1927
1926
  };
1928
1927
  if (
1929
1928
  this.info.shopInfo?.shopId &&
1930
1929
  this.info.shopInfo?.venderId &&
1931
1930
  (this.info.shopInfo.shopId == shopId || this.info.shopInfo.venderId == venderId)
1932
1931
  ) {
1933
1932
  this.info.queryInfo.shopId = this.info.shopInfo.shopId;
1934
1933
  this.info.queryInfo.venderId = this.info.shopInfo.venderId;
1935
1934
  console.log(
1936
1935
  '当前存储的店铺shopId和venderId与下发的店铺信息shopId或者venderId为同一个,补充shopId或者venderId查询参数',
1937
1936
  this.info.queryInfo,
1938
1937
  );
1939
1938
  }
1940
1939
  }
1941
1940
  this.info.queryInfo['shopId'] &&
1942
1941
  (this.info.queryInfo['shopId'] = `${this.info.queryInfo['shopId']}`);
1943
1942
  this.info.queryInfo['venderId'] &&
1944
1943
  (this.info.queryInfo['venderId'] = `${this.info.queryInfo['venderId']}`);
1945
1944
  console.log(
1946
1945
  'h5==获取店铺下发查询参数\n',
1947
1946
  query,
1948
1947
  '\n获取店铺最后查询参数\n',
1949
1948
  this.info.queryInfo,
1950
1949
  '\n是否为更新店铺状态\n',
1951
1950
  updateShopInfoState,
1952
1951
  );
1953
1952
  const changeArea = un_area && un_area.length > 0 ? un_area : isPc && ipLoc_djd ? ipLoc_djd : '';
1954
1953
  if (changeArea) {
1955
1954
  const getBottomAreaStr = changeArea.replace(/-/g, '_');
1956
1955
  this.info.pageInfo.address = getBottomAreaStr;
1957
1956
  this.info.pageInfo.un_area = getBottomAreaStr;
1958
1957
  this.info.pageInfo.addressCommaStr = getBottomAreaStr.replace(/_/g, ',');
1959
1958
  }
1960
1959
  }
1961
1960
 
1962
1961
  dealLoadSdkList() {
1963
1962
  const globalLoadJsList = window?.shopGlobalSwitch?.asyncLoadJsList ?? [];
1964
1963
  const businessLoadJsList = window?.PAGE_DATA?.businessData?.asyncLoadJsList ?? [];
1965
1964
  const concatLoadJsList = [].concat(globalLoadJsList, businessLoadJsList);
1966
1965
  let mergeLoadJsList = globalLoadJsList;
1967
1966
  try {
1968
1967
  mergeLoadJsList = concatLoadJsList.reduce((accArr: any[], current: any) => {
1969
1968
  const getFindIndex = accArr.findIndex((item) => item?.fileName === current?.fileName);
1970
1969
  getFindIndex !== -1
1971
1970
  ? (accArr[getFindIndex] = { ...accArr[getFindIndex], ...current })
1972
1971
  : accArr.push(current);
1973
1972
  return accArr;
1974
1973
  }, []);
1975
1974
  } catch (e) {
1976
1975
  console.log('LoadJsList合并错误', e);
1977
1976
  }
1978
1977
  console.log(
1979
1978
  'globalLoadJsList',
1980
1979
  globalLoadJsList,
1981
1980
  'businessLoadJsList',
1982
1981
  businessLoadJsList,
1983
1982
  '两个加载jsList集合合并完成',
1984
1983
  mergeLoadJsList,
1985
1984
  );
1986
1985
  this.loadJsSdkList = mergeLoadJsList;
1987
1986
  return this.loadJsSdkList;
1988
1987
  }
1989
1988
 
1990
1989
  renderNextTickLoadSdk(delayTime = 1000, callback) {
1991
1990
  Taro.nextTick(() => {
1992
1991
  console.log(
1993
1992
  '页面渲染的下一帧执行的js加载方法,当前nextTick存在state的渲染问题,先延迟1s=======',
1994
1993
  );
1995
1994
  setTimeout(() => {
1996
1995
  this.loadOtherSdk(LoadJsInitTriggerType.NRXT_TICK, this.loadJsSdkList);
1997
1996
  typeof callback === 'function' && callback();
1998
1997
  }, delayTime);
1999
1998
  });
2000
1999
  }
2001
2000
 
2002
2001
  async loadOtherSdk(triggerType = LoadJsInitTriggerType.NOW, loadJsList: any[] = []) {
2003
2002
  const getLoadJsList =
2004
2003
  Array.isArray(loadJsList) && loadJsList.length > 0 ? loadJsList : this.dealLoadSdkList();
2005
2004
  const getLoadFilterList = getLoadJsList.filter((item) => {
2006
2005
  if (isJdAndHarmonyDevice && item.fileName === 'addCartJs') {
2007
2006
  item.initLoadType = undefined;
2008
2007
  }
2009
2008
  const getInitLoadEnvType = item?.initLoadEnvType || LoadJsInitLoadEnvType.ALL;
2010
2009
  let getLoastLoadEventState = true;
2011
2010
  if (getInitLoadEnvType === LoadJsInitLoadEnvType.JD_APP) {
2012
2011
  getLoastLoadEventState = isJdApp;
2013
2012
  }
2014
2013
  else if (getInitLoadEnvType === LoadJsInitLoadEnvType.M) {
2015
2014
  getLoastLoadEventState = !isJdApp || !!isJdAndHarmonyDevice;
2016
2015
  }
2017
2016
  const getInitTriggerType =
2018
2017
  isJdApp && item?.initJdAppTriggerType
2019
2018
  ? item?.initJdAppTriggerType
2020
2019
  : item?.initTriggerType || LoadJsInitTriggerType.NOW;
2021
2020
  const getInitLinkTriggerWay = window?.PAGE_DATA[item?.initLinkTriggerWay] || false;
2022
2021
  return getLoastLoadEventState && getInitTriggerType === triggerType && getInitLinkTriggerWay;
2023
2022
  });
2024
2023
  console.log(
2025
2024
  '获取当前触发方式',
2026
2025
  triggerType,
2027
2026
  '获取当前最后加载的js集合',
2028
2027
  getLoadFilterList,
2029
2028
  '过滤前的加载集合',
2030
2029
  getLoadJsList,
2031
2030
  );
2032
2031
  const loadTasks =
2033
2032
  getLoadFilterList.length > 0
2034
2033
  ? getLoadFilterList.map((item) => {
2035
2034
  const isLoadState = /sgm/.test(item?.fileName)
2036
2035
  ? window?.shopGlobalSwitch?.openSgm === 'true'
2037
2036
  : true;
2038
2037
  if (!isLoadState) {
2039
2038
  return Promise.resolve(true);
2040
2039
  }
2041
2040
  return this.loadItemSdkPromise(item)
2042
2041
  .then((res) => {
2043
2042
  console.info('当前js地址' + item?.src, '加载状态', res);
2044
2043
  const isFileNameNewDraSdkJs = res?.fileName === 'newDraSdkJs';
2045
2044
  if (isFileNameNewDraSdkJs && window?.dra?.run) {
2046
2045
  const getNewdraEnableShopIdPercentObj =
2047
2046
  window?.PAGE_DATA?.businessData?.newDraEnableShopIdPercent || null;
2048
2047
  const getNewdraEnableVenderIdPercentObj =
2049
2048
  window?.PAGE_DATA?.businessData?.newDraEnableVenderIdPercent || null;
2050
2049
  let canInitDraRun = true;
2051
2050
  if (getNewdraEnableShopIdPercentObj || getNewdraEnableVenderIdPercentObj) {
2052
2051
  canInitDraRun = this.shouldPercentExecuteNewDra(
2053
2052
  this.getNewDraEnablePercentNum(),
2054
2053
  );
2055
2054
  }
2056
2055
  if (canInitDraRun) {
2057
2056
  window.dra.run('init', { aid: res?.aid });
2058
2057
  window.dra.run('start');
2059
2058
  }
2060
2059
  }
2061
2060
  return true;
2062
2061
  })
2063
2062
  .catch((err) => {
2064
2063
  console.info('当前js地址加载异常', item?.src);
2065
2064
  window?.fetchErrorData &&
2066
2065
  window.fetchErrorData({
2067
2066
  title: '公共js加载异常',
2068
2067
  type: 'jsLoad',
2069
2068
  data: err,
2070
2069
  });
2071
2070
  return true;
2072
2071
  });
2073
2072
  })
2074
2073
  : [];
2075
2074
  return loadTasks.length ? Promise.allSettled(loadTasks) : Promise.resolve([]);
2076
2075
  }
2077
2076
 
2078
2077
  shouldPercentExecuteNewDra(percent) {
2079
2078
  if (percent <= 0) return false;
2080
2079
  if (percent >= 100) return true;
2081
2080
  const getRes = Math.random() < percent / 100;
2082
2081
  console.log('获取dra初始化执行的概率为', percent, '执行结果', getRes);
2083
2082
  return getRes;
2084
2083
  }
2085
2084
 
2086
2085
  getNewDraEnablePercentNum() {
2087
2086
  const getNewdraEnableShopIdPercent =
2088
2087
  window?.PAGE_DATA?.businessData?.newDraEnableShopIdPercent || {};
2089
2088
  const getNewdraEnableVenderIdPercent =
2090
2089
  window?.PAGE_DATA?.businessData?.newDraEnableVenderIdPercent || {};
2091
2090
  const getShopId = parseQueryUrlObj?.shopId || '';
2092
2091
  const getVenderId = parseQueryUrlObj?.venderId || '';
2093
2092
  const getShopIdDraEnablePercent = getNewdraEnableShopIdPercent[getShopId]
2094
2093
  ? getNewdraEnableShopIdPercent[getShopId]
2095
2094
  : getNewdraEnableShopIdPercent?.ids?.includes(getShopId)
2096
2095
  ? getNewdraEnableShopIdPercent?.idsNumber
2097
2096
  : -1;
2098
2097
  const getVenderIdDraEnablePercent = getNewdraEnableVenderIdPercent[getVenderId]
2099
2098
  ? getNewdraEnableVenderIdPercent[getVenderId]
2100
2099
  : getNewdraEnableVenderIdPercent?.ids?.includes(getVenderId)
2101
2100
  ? getNewdraEnableVenderIdPercent?.idsNumber
2102
2101
  : -1;
2103
2102
  if (getShopIdDraEnablePercent > -1 || getVenderIdDraEnablePercent > -1) {
2104
2103
  return getShopIdDraEnablePercent || getVenderIdDraEnablePercent;
2105
2104
  }
2106
2105
  return 100;
2107
2106
  }
2108
2107
  loadScriptEle(jsInfo, resolve, reject) {
2109
2108
  const getFileName = jsInfo?.fileName;
2110
2109
  if (getFileName) {
2111
2110
  const getEleId = `J_loadJs_${getFileName}`;
2112
2111
  const getEle = document.getElementById(getEleId);
2113
2112
  if (!getEle) {
2114
2113
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
2115
2114
  const _sgmEle = document.createElement('script');
2116
2115
  _sgmEle.id = getEleId;
2117
2116
  _sgmEle.onload = function () {
2118
2117
  resolve({
2119
2118
  ...jsInfo,
2120
2119
  jsTip: 'js加载成功',
2121
2120
  });
2122
2121
  };
2123
2122
  _sgmEle.onerror = function () {
2124
2123
  reject({
2125
2124
  ...jsInfo,
2126
2125
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2127
2126
  jsReqError: '当前js创建标签触发onerror异常回调,请排查网络络错误或语法错误或运行时错误',
2128
2127
  });
2129
2128
  };
2130
2129
  const dataAttrList = ['timeout', 'fileName', 'env'];
2131
2130
  const getJsInfoKeyList = Object.keys(jsInfo);
2132
2131
  getJsInfoKeyList.forEach((key) => {
2133
2132
  if (key === 'async') {
2134
2133
  _sgmEle.async = jsInfo[key];
2135
2134
  } else if (key === 'crossOrigin') {
2136
2135
  _sgmEle.crossOrigin = jsInfo[key];
2137
2136
  } else if (key === 'src') {
2138
2137
  _sgmEle.src = `${jsInfo[key]}`;
2139
2138
  } else if (dataAttrList.includes(key) || /init/.test(key)) {
2140
2139
  _sgmEle.setAttribute(`data-${key}`, jsInfo[key]);
2141
2140
  } else {
2142
2141
  _sgmEle.setAttribute(key, jsInfo[key]);
2143
2142
  }
2144
2143
  });
2145
2144
  document.head.appendChild(_sgmEle);
2146
2145
  } else {
2147
2146
  console.log(`当前${jsInfo?.fileName || 'js'}已经存在页面中,可以直接调用相关方法`, jsInfo);
2148
2147
  resolve({
2149
2148
  ...jsInfo,
2150
2149
  jsTip: 'js本身已存在页面中',
2151
2150
  });
2152
2151
  }
2153
2152
  } else {
2154
2153
  console.warn('当前js资源信息缺少必要的参数fileName,请关注', jsInfo);
2155
2154
  }
2156
2155
  }
2157
2156
 
2158
2157
  loadItemSdkPromise(jsInfo: Record<string, any> = {}): Promise<any> {
2159
2158
  if (jsInfo?.src) {
2160
2159
  const getInitLoadType =
2161
2160
  isJdApp && jsInfo?.initJdAppLoadType
2162
2161
  ? jsInfo?.initJdAppLoadType
2163
2162
  : jsInfo?.initLoadType || LoadJsInitLoadType.ALL;
2164
2163
  if (getInitLoadType !== LoadJsInitLoadType.NONE) {
2165
2164
  const getFileKeyName = jsInfo?.fileName || jsInfo?.src;
2166
2165
  if (!this.loadJsSdkListCachePromise[getFileKeyName]) {
2167
2166
  if (getInitLoadType !== LoadJsInitLoadType.INSERT_ELE) {
2168
2167
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
2169
2168
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
2170
2169
  try {
2171
2170
  const jsXhrRequest = new XMLHttpRequest();
2172
2171
  jsXhrRequest.timeout = jsInfo?.timeout ?? 2000;
2173
2172
  const jsUrl = `${jsInfo?.src}`;
2174
2173
  jsXhrRequest.open('GET', jsUrl, true);
2175
2174
  jsXhrRequest.onreadystatechange = () => {
2176
2175
  if (jsXhrRequest.readyState === 4) {
2177
2176
  const getReqStatus = jsXhrRequest.status;
2178
2177
  const statusText = jsXhrRequest.statusText;
2179
2178
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
2180
2179
  const getInsetHeadState = getInitLoadType === LoadJsInitLoadType.ALL;
2181
2180
  if (getInsetHeadState) {
2182
2181
  this.loadScriptEle(jsInfo, resolve, reject);
2183
2182
  } else {
2184
2183
  resolve({
2185
2184
  ...jsInfo,
2186
2185
  jsTip: 'js请求成功,暂未插入head节点,业务自行单独插入',
2187
2186
  });
2188
2187
  }
2189
2188
  getReqStatus !== 200 &&
2190
2189
  draBusinessCustomReport({
2191
2190
  eventName: 'business',
2192
2191
  errorName: 'js_load_special_code',
2193
2192
  errorMessage: '当前js加载成功,状态非200,特殊上报观察',
2194
2193
  extraData: JSON.stringify({
2195
2194
  msg: '当前js加载成功,状态非200,特殊上报观察',
2196
2195
  jsReqState: getReqStatus,
2197
2196
  env: getSgmCustomCode('js_load_special_code'),
2198
2197
  data: jsInfo,
2199
2198
  }),
2200
2199
  });
2201
2200
  } else {
2202
2201
  const getRes = {
2203
2202
  ...jsInfo,
2204
2203
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2205
2204
  jsReqError: `请求状态异常,状态码为${getReqStatus},statusText:${statusText}`,
2206
2205
  jsReqState: getReqStatus,
2207
2206
  };
2208
2207
  console.log('当前js请求状态异常,具体信息见', getRes);
2209
2208
  reject(getRes);
2210
2209
  }
2211
2210
  }
2212
2211
  };
2213
2212
  jsXhrRequest.onerror = () => {
2214
2213
  const getRes = {
2215
2214
  ...jsInfo,
2216
2215
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2217
2216
  jsReqError: '请求错误',
2218
2217
  };
2219
2218
  console.log('当前js请求错误', getRes);
2220
2219
  jsXhrRequest.abort();
2221
2220
  reject(getRes);
2222
2221
  };
2223
2222
  jsXhrRequest.ontimeout = () => {
2224
2223
  const getRes = {
2225
2224
  ...jsInfo,
2226
2225
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2227
2226
  jsReqError: `请求${jsXhrRequest.timeout}ms超时异常`,
2228
2227
  jsReqState: jsXhrRequest.status,
2229
2228
  };
2230
2229
  console.log('当前js请求超时异常', getRes);
2231
2230
  jsXhrRequest.abort();
2232
2231
  reject(getRes);
2233
2232
  };
2234
2233
  jsXhrRequest.send();
2235
2234
  } catch (e) {
2236
2235
  console.log('执行js请求异常', e);
2237
2236
  reject({
2238
2237
  ...jsInfo,
2239
2238
  env: getSgmCustomCode(jsLoadErrorSgmCode),
2240
2239
  jsReqError: '未知异常',
2241
2240
  error: e,
2242
2241
  });
2243
2242
  }
2244
2243
  });
2245
2244
  } else {
2246
2245
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
2247
2246
  return this.loadScriptEle(jsInfo, resolve, reject);
2248
2247
  });
2249
2248
  }
2250
2249
  }
2251
2250
  return this.loadJsSdkListCachePromise[getFileKeyName];
2252
2251
  } else {
2253
2252
  return Promise.resolve({
2254
2253
  ...jsInfo,
2255
2254
  jsTip: 'js加载方式设置为不加载,当前不做处理',
2256
2255
  });
2257
2256
  }
2258
2257
  } else {
2259
2258
  return Promise.reject(jsInfo);
2260
2259
  }
2261
2260
  }
2262
2261
 
2263
2262
  createLanguagePromise() {
2264
2263
  const getLanguageConfig = window?.shopGlobalSwitch?.language || {};
2265
2264
  if (!this.languageCacheProimse) {
2266
2265
  this.languageCacheProimse = new Promise((resolve, reject) => {
2267
2266
  const { fileName, prefixUrl } = getLanguageConfig;
2268
2267
  console.log('getLanguageConfig', getLanguageConfig, 'languageNowType', languageNowType);
2269
2268
  const dealLanguageFile = () => {
2270
2269
  this.getLanguageFilePromise(getLanguageConfig, languageNowType)
2271
2270
  .then((res: any) => {
2272
2271
  if (res && res?.data) {
2273
2272
  this.languageJsonData = res.data;
2274
2273
 
2275
2274
  setTimeout(() => {
2276
2275
  const getOtherLanguageList = languageTypeList.filter(
2277
2276
  (item) => item !== languageNowType,
2278
2277
  );
2279
2278
  getOtherLanguageList.length > 0 &&
2280
2279
  getOtherLanguageList.map((languageTypeKey) => {
2281
2280
  this.getLanguageFilePromise(getLanguageConfig, languageTypeKey);
2282
2281
  });
2283
2282
  }, 3000);
2284
2283
  resolve(res);
2285
2284
  } else {
2286
2285
  reject(res);
2287
2286
  }
2288
2287
  })
2289
2288
  .catch((err) => {
2290
2289
  reject(err);
2291
2290
  });
2292
2291
  };
2293
2292
  if (fileName && prefixUrl) {
2294
2293
  const getLangStorageKey = `jshopx_lang_${languageNowType}`;
2295
2294
  const getLocalLangRes = getTaroStorageKeyValue(getLangStorageKey);
2296
2295
  if (getLocalLangRes) {
2297
2296
  try {
2298
2297
  const getLocalLangJsonData =
2299
2298
  typeof getLocalLangRes === 'string' ? JSON.parse(getLocalLangRes) : getLocalLangRes;
2300
2299
  if (getLocalLangJsonData?.fileName && getLocalLangJsonData?.data) {
2301
2300
  if (getLocalLangJsonData?.fileName === fileName) {
2302
2301
  const geThisLangData = getLocalLangJsonData.data;
2303
2302
  this.languageJsonData = geThisLangData;
2304
2303
  return resolve({
2305
2304
  ...getLanguageConfig,
2306
2305
  languageNowType,
2307
2306
  data: geThisLangData,
2308
2307
  });
2309
2308
  } else {
2310
2309
  dealLanguageFile();
2311
2310
  }
2312
2311
  } else {
2313
2312
  dealLanguageFile();
2314
2313
  }
2315
2314
  } catch (e) {
2316
2315
  return reject({
2317
2316
  languageNowType,
2318
2317
  msg: '转换错误',
2319
2318
  ...getLanguageConfig,
2320
2319
  });
2321
2320
  }
2322
2321
  } else {
2323
2322
  dealLanguageFile();
2324
2323
  }
2325
2324
  } else {
2326
2325
  return reject({
2327
2326
  languageNowType,
2328
2327
  msg: '文件对象下发异常',
2329
2328
  ...getLanguageConfig,
2330
2329
  });
2331
2330
  }
2332
2331
  });
2333
2332
  }
2334
2333
  return this.languageCacheProimse;
2335
2334
  }
2336
2335
 
2337
2336
  getLanguageFilePromise(info, languageTypeKey) {
2338
2337
  const { fileName, prefixUrl, timeout } = info || {};
2339
2338
  const getUrl = `${prefixUrl}${fileName}_${languageTypeKey}.json`;
2340
2339
  return new Promise((resolve, reject) => {
2341
2340
  const langLoadErrorSgmCode = `languageLoadError_${fileName || 'lang.json'}`;
2342
2341
  try {
2343
2342
  const langXhrRequest = new XMLHttpRequest();
2344
2343
  langXhrRequest.timeout = timeout || 2000;
2345
2344
  langXhrRequest.open('GET', getUrl, true);
2346
2345
  langXhrRequest.responseType = 'json';
2347
2346
  langXhrRequest.onreadystatechange = () => {
2348
2347
  if (langXhrRequest.readyState === 4) {
2349
2348
  const getReqStatus = langXhrRequest.status;
2350
2349
  const statusText = langXhrRequest.statusText;
2351
2350
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
2352
2351
  const getData = langXhrRequest?.response || false;
2353
2352
  if (getData) {
2354
2353
  setTaroStorage(`jshopx_lang_${languageTypeKey}`, {
2355
2354
  fileName,
2356
2355
  data: getData,
2357
2356
  });
2358
2357
  resolve({
2359
2358
  ...info,
2360
2359
  languageTypeKey,
2361
2360
  data: getData,
2362
2361
  });
2363
2362
  } else {
2364
2363
  reject({
2365
2364
  ...info,
2366
2365
  languageTypeKey,
2367
2366
  msg: '数据获取异常',
2368
2367
  });
2369
2368
  }
2370
2369
  } else {
2371
2370
  const getRes = {
2372
2371
  ...info,
2373
2372
  languageTypeKey,
2374
2373
  env: getSgmCustomCode(langLoadErrorSgmCode),
2375
2374
  msg: `请求状态异常,状态码为${getReqStatus},statusText:${statusText}`,
2376
2375
  };
2377
2376
  console.log('当前lang请求状态异常,具体信息见', getRes);
2378
2377
  reject(getRes);
2379
2378
  }
2380
2379
  }
2381
2380
  };
2382
2381
  langXhrRequest.onerror = () => {
2383
2382
  const getRes = {
2384
2383
  ...info,
2385
2384
  env: getSgmCustomCode(langLoadErrorSgmCode),
2386
2385
  msg: '请求错误',
2387
2386
  };
2388
2387
  console.log('当前lang请求错误', getRes);
2389
2388
  langXhrRequest.abort();
2390
2389
  reject(getRes);
2391
2390
  };
2392
2391
  langXhrRequest.ontimeout = () => {
2393
2392
  const getRes = {
2394
2393
  ...info,
2395
2394
  msg: `请求${langXhrRequest.timeout}ms超时异常,状态${langXhrRequest.status}`,
2396
2395
  };
2397
2396
  console.log('执行lang多语言请求超时异常', getRes);
2398
2397
  langXhrRequest.abort();
2399
2398
  reject(getRes);
2400
2399
  };
2401
2400
  langXhrRequest.send();
2402
2401
  } catch (e) {
2403
2402
  console.log('执行lang多语言请求异常', e);
2404
2403
  reject({
2405
2404
  ...info,
2406
2405
  env: getSgmCustomCode(langLoadErrorSgmCode),
2407
2406
  msg: '未知异常',
2408
2407
  error: e,
2409
2408
  });
2410
2409
  }
2411
2410
  });
2412
2411
  }
2412
+ import Taro from '@tarojs/taro';
2413
2413
  BUSINESS_TYPE,
2414
2414
  cacheAppKey,
2415
2415
  cacheAppUuidKey,
2416
2416
  cacheH5LbsAddressKey,
2417
2417
  JSSDK_APP_WEBVIEW_CODE,
2418
2418
  LoadJsInitLoadEnvType,
2419
2419
  LoadJsInitLoadType,
2420
2420
  LoadJsInitTriggerType,
2421
2421
  MPAAS_CONFIG_APP_LOW_VERSION,
2422
2422
  MPAAS_CONFIG_APP_VERSION,
2423
2423
  SECTION_HOME_TAB_NAME_TYPE,
2424
2424
  SECTION_HOME_TAB_TYPE,
2425
2425
  TaroEventType,
2426
2426
  WX_BUSINESS_TYPE,
2427
2427
  WXAPP_BIZ_KEY,
2428
2428
  WXAPP_BIZ_SHOP_LIGHT_KEY,
2429
2429
  languageTypeList,
2430
2430
  getSystemInfos,
2431
2431
  getTaroStorageKeyValue,
2432
2432
  ipLoc_djd,
2433
2433
  setTaroStorage,
2434
2434
  isInJdAppH5DebugMode,
2435
2435
  callRouterAndroid,
2436
2436
  callRouterIOS,
2437
2437
  getMPaasConfigByBussinessKey,
2438
2438
  dealNativePixelToCssPixel,
2439
2439
  draBusinessCustomReport,
2440
2440
  draBusinessCustomLogReport,
2441
2441
  isAndroidDevice,
2442
2442
  isH5AndJingGouMini,
2443
2443
  isIosDevice,
2444
2444
  isJdAndAndroidDevice,
2445
2445
  isObject,
2446
2446
  isPc,
2447
2447
  isString,
2448
2448
  jdAppVersion,
2449
2449
  jdAppVersionStr,
2450
2450
  serialize,
2451
2451
  languageNowType,
2452
2452
  urlCookie,
2453
2453
  isAscfApp,
2454
2454
  jdAppVersionCompare,
2455
2455
  parseQueryUrlObj,
2456
2456
  abTestLabels: {},
2457
2457
  nonSellableSkuids: {},
2458
2458
  loginState: false,
2459
2459
  cookiesStr: '',
2460
2460
  userInfo: userPinKey,
2461
2461
  isImmersive:
2462
2462
  !window?.shopGlobalSwitch?.disableImmersive &&
2463
2463
  isJdApp &&
2464
2464
  window.location?.search.includes('immersive=1'),
2465
2465
  isJingGouMiniViewState: false,
2466
2466
  isJingxiMiniViewState: false,
2467
2467
  baseAddCartSwitch: true,
2468
2468
  pageInfo: {
2469
2469
  wxBusinessType: WX_BUSINESS_TYPE.NO,
2470
2470
  address: '',
2471
2471
  addressCommaStr: '',
2472
2472
  fullAddress: '',
2473
2473
  un_area: '',
2474
2474
  userLbsAddress: '',
2475
2475
  vapptype: '1',
2476
2476
  pageType: 'home',
2477
2477
  isExposureState: false,
2478
2478
  moduleId: '',
2479
2479
  entrance: '',
2480
2480
  dataType: BUSINESS_TYPE.ONLINE,
2481
2481
  floorExposureInfo: {},
2482
2482
  floorVideInfo: {},
2483
2483
  productVideInfo: {},
2484
2484
  tabsLoadAllDataInfo: {
2485
2485
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: false,
2486
2486
  },
2487
2487
  updateShopInfosAllState: false,
2488
2488
  isVipShop: false,
2489
2489
  isJdShowNativeImmersivePlayer: false,
2490
2490
  isSuperBrandShop: false,
2491
2491
  ...shopConfig,
2492
2492
  pageScrollTop: 0,
2493
2493
  pageIdxHeightInfo: {
2494
2494
  list: [],
2495
2495
  },
2496
2496
  shopNavBarHeight: 0,
2497
2497
  },
2498
2498
  defaultQueryLogInfo: {
2499
2499
  sourceType: 'JDshop',
2500
2500
  sourceValue: '',
2501
2501
  moduleId: 'none',
2502
2502
  entrance: 'none',
2503
2503
  },
2504
2504
  sysInfo: {
2505
2505
  windowWidth: isPc ? 375 : 0,
2506
2506
  containerWidth: isPc ? 375 : 0,
2507
2507
  windowHeight: 0,
2508
2508
  netWorkType: '4g',
2509
2509
  jdBottomBarHeight: 0,
2510
2510
  jdNativeHeaderHeight: 0,
2511
2511
  isJdTabletDevice: false,
2512
2512
  isJdTabletLandscape: false,
2513
2513
  },
2514
2514
  queryInfo: {},
2515
2515
  shopInfo: {},
2516
2516
  openAppData: {},
2517
2517
  public info: CommonInterFace.BaseConfigInfo;
2518
2518
  public config: {
2519
2519
  [key: string]: any;
2520
2520
  };
2521
2521
  public lazyContainer: CommonInterFace.lazyContainer;
2522
2522
  public renderedIsvComponents: CommonInterFace.renderedIsvComponents;
2523
2523
  public rootEleNode: HTMLElement | null;
2524
2524
  public checkStatusAndLoginPromise: object | null;
2525
2525
  private jmfeRegisterStatePromise: Promise<any> | null;
2526
2526
  private jdScreenSizeInfoPromise: Promise<any> | null;
2527
2527
  private rootEleWidthRegisterPromise: Promise<any> | null;
2528
2528
  private loadJsH5tagStatePromise: Promise<any> | null;
2529
2529
  private loadJsApiRequestStatePromise: Promise<any> | null;
2530
2530
  private jmfeRegisterState: boolean;
2531
2531
  public loadJsSdkList: {
2532
2532
  src: string;
2533
2533
  timeout: number;
2534
2534
  fileName: string;
2535
2535
  initTriggerType: typeof LoadJsInitTriggerType;
2536
2536
  initLinkTriggerWay:
2537
2537
  | 'asyncLoadAppSdkJs'
2538
2538
  | 'asyncLoadHandlerJs'
2539
2539
  | 'asyncLoadReportJs'
2540
2540
  | 'asyncLoadMtkJs'
2541
2541
  | 'asyncLoadSecurityJs'
2542
2542
  | 'asyncLoadSgmJs'
2543
2543
  | 'asyncLoadCartJs'
2544
2544
  | 'asyncLoadNewDraSdkJs'
2545
2545
  | 'asyncLoadH5TagJs';
2546
2546
  initLoadEnvType: typeof LoadJsInitLoadEnvType;
2547
2547
  defer?: 'true';
2548
2548
  async?: 'true';
2549
2549
  crossOrigin: 'anonymous' | '';
2550
2550
  }[];
2551
2551
  public loadJsSdkListCachePromise: any;
2552
2552
  public rootEleInitWidth: number;
2553
2553
  public lbsAddressCachePromise: Promise<any> | null;
2554
2554
  public languageCacheProimse: Promise<any> | null;
2555
2555
  public languageJsonData: any | null;
2556
2556
  public businessWorkerReady: boolean;
2557
2557
  public businessWorkerReadyPromise: Promise<any> | null;
2558
2558
  constructor(opt) {
2559
2559
  this.info = this._getConfig(opt);
2560
2560
  this.config = {};
2561
2561
  this.loadJsSdkList = [];
2562
2562
  this.loadJsSdkListCachePromise = {};
2563
2563
  this.lazyContainer = {
2564
2564
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_WELL_CHOSEN]]: {
2565
2565
  appLazyContainerList: [],
2566
2566
  appLazyFinishContainerList: [],
2567
2567
  },
2568
2568
  [SECTION_HOME_TAB_NAME_TYPE[SECTION_HOME_TAB_TYPE.HOME_PROMOTION]]: {
2569
2569
  appLazyContainerList: [],
2570
2570
  appLazyFinishContainerList: [],
2571
2571
  },
2572
2572
  };
2573
2573
  this.renderedIsvComponents = {};
2574
2574
  this.rootEleNode = document.querySelector('body');
2575
2575
  this.checkStatusAndLoginPromise = null;
2576
2576
  this.jmfeRegisterStatePromise = null;
2577
2577
  this.jdScreenSizeInfoPromise = null;
2578
2578
  this.rootEleWidthRegisterPromise = null;
2579
2579
  this.lbsAddressCachePromise = null;
2580
2580
  this.languageCacheProimse = null;
2581
2581
  this.businessWorkerReady = false;
2582
2582
  this.businessWorkerReadyPromise = null;
2583
2583
  this.loadJsH5tagStatePromise = null;
2584
2584
  this.loadJsApiRequestStatePromise = null;
2585
2585
  this.languageJsonData = langeJsonDataForCn;
2586
2586
  this.rootEleInitWidth = this.getRootEleWindowWidthInfo().getRootEleWidth || -1;
2587
2587
  this._init();
2588
2588
  if (isJdApp) {
2589
2589
  this.jmfeReayPromise().then(() => {
2590
2590
  this.jdWorkerReadyPromise();
2591
2591
  initAccessibility();
2592
2592
  });
2593
2593
  this._getJdPadMinWidthForListen() && this.getPadWindowRootEleWidthPromise();
2594
2594
  }
2595
2595
  }
2596
2596
  _getConfig(opt) {
2597
2597
  return Object.assign({}, DefaultConfig, opt);
2598
2598
  }
2599
2599
  _init() {
2600
2600
  this.loadOtherSdk();
2601
2601
  this.checkJdAddCartState();
2602
2602
  this.checkPageDomHeightToReport();
2603
2603
  }
2604
2604
  checkPageDomHeightToReport() {
2605
2605
  Taro.nextTick(() => {
2606
2606
  setTimeout(() => {
2607
2607
  const getReportData = {
2608
2608
  containerFloorLisHeight: -1,
2609
2609
  appHeight: -1,
2610
2610
  };
2611
2611
  const getAppEle = document.getElementById('app');
2612
2612
  const getFloorContainerEle = document.getElementById('J_shopContainerFloorList');
2613
2613
  const getNetWorkEle = document.querySelector('.J_shopNetwork');
2614
2614
  getFloorContainerEle &&
2615
2615
  (getReportData.containerFloorLisHeight =
2616
2616
  getFloorContainerEle?.getBoundingClientRect()?.height ?? -1);
2617
2617
  getAppEle && (getReportData.appHeight = getAppEle?.getBoundingClientRect()?.height ?? -1);
2618
2618
  const getMaxHeight = Math.max(
2619
2619
  getReportData.appHeight,
2620
2620
  getReportData.containerFloorLisHeight,
2621
2621
  );
2622
2622
  if (!getNetWorkEle && getMaxHeight > -1 && getMaxHeight < 80) {
2623
2623
  draBusinessCustomReport({
2624
2624
  eventName: 'business',
2625
2625
  errorName: 'pageDomHeightErrorCheck',
2626
2626
  errorMessage:
2627
2627
  '当前页面总高度异常小于80px,没有兜底network组件,可能空窗,请检查核对详细信息',
2628
2628
  extraData: JSON.stringify({
2629
2629
  data: getReportData,
2630
2630
  isJdApp,
2631
2631
  }),
2632
2632
  });
2633
2633
  }
2634
2634
  }, window?.shopGlobalSwitch?.checkPageDomHeightTime || 4000);
2635
2635
  });
2636
2636
  }
2637
2637
 
2638
2638
  checkJdAddCartState() {
2639
2639
  const getJdAppForNotMainRemoveCartUaList = isJdApp
2640
2640
  ? window?.PAGE_DATA?.businessData?.jdAppForNotMainRemoveCartUaList
2641
2641
  : undefined;
2642
2642
  if (
2643
2643
  getJdAppForNotMainRemoveCartUaList &&
2644
2644
  Array.isArray(getJdAppForNotMainRemoveCartUaList) &&
2645
2645
  getJdAppForNotMainRemoveCartUaList.length > 0
2646
2646
  ) {
2647
2647
  const setFilterReg = new RegExp(getJdAppForNotMainRemoveCartUaList.join('|'), 'i');
2648
2648
  this.info.baseAddCartSwitch = !setFilterReg.test(window.navigator.userAgent);
2649
2649
  }
2650
2650
  }
2651
2651
 
2652
2652
  loadApiSafeSteadyReayPromise() {
2653
2653
  if (!this.loadJsApiRequestStatePromise) {
2654
2654
  this.loadJsApiRequestStatePromise = this.loadOtherSdk(LoadJsInitTriggerType.API_REQUEST);
2655
2655
  }
2656
2656
  return this.loadJsApiRequestStatePromise;
2657
2657
  }
2658
2658
 
2659
2659
  loadH5tagReayPromise() {
2660
2660
  if (!this.loadJsH5tagStatePromise) {
2661
2661
  const h5TagJs = this.loadJsSdkList.find((e) => e.fileName === 'h5TagJs');
2662
2662
  this.loadJsH5tagStatePromise = !h5TagJs
2663
2663
  ? Promise.resolve(true)
2664
2664
  : this.loadOtherSdk(LoadJsInitTriggerType.NOW, [
2665
2665
  Object.assign({}, h5TagJs, {
2666
2666
  initTriggerType: LoadJsInitTriggerType.NOW,
2667
2667
  }),
2668
2668
  ]);
2669
2669
  }
2670
2670
  return this.loadJsH5tagStatePromise;
2671
2671
  }
2672
2672
 
2673
2673
  jmfeReayPromise(): Promise<any> {
2674
2674
  if (isJdApp) {
2675
2675
  if (this.jmfeRegisterState) {
2676
2676
  return Promise.resolve(true);
2677
2677
  } else {
2678
2678
  !this.jmfeRegisterStatePromise &&
2679
2679
  (this.jmfeRegisterStatePromise = new Promise((resolve, reject) => {
2680
2680
  ready('jmfe', 3000)
2681
2681
  .then(() => {
2682
2682
  window?.jmfe && window.jmfe.registerCode(JSSDK_APP_WEBVIEW_CODE);
2683
2683
  this.jmfeRegisterState = true;
2684
2684
  resolve(true);
2685
2685
  console.log(
2686
2686
  '松果app内初始化注册jmfe认证完成',
2687
2687
  window?.jmfe,
2688
2688
  '当前版本',
2689
2689
  window?.jmfe?.VERSION,
2690
2690
  );
2691
2691
  })
2692
2692
  .catch((err) => {
2693
2693
  console.error('jmfe ready error', err);
2694
2694
  reject(false);
2695
2695
  });
2696
2696
  }));
2697
2697
  return this.jmfeRegisterStatePromise;
2698
2698
  }
2699
2699
  } else {
2700
2700
  return Promise.reject(false);
2701
2701
  }
2702
2702
  }
2703
2703
 
2704
2704
  jdMarkWorkerReady(resolve: (value: any) => void, workerVersion, source: string) {
2705
2705
  if (!this.businessWorkerReady) {
2706
2706
  const getResTime = Date.now();
2707
2707
  console.info(`jd worker注册成功,版本为${workerVersion}, 当前注册成功为${source}返回,时间:${getResTime}`);
2708
2708
  draBusinessCustomLogReport(
2709
2709
  `APP店铺业务worker注册成功,版本为${workerVersion},当前注册成功为${source}返回,时间戳${getResTime}, 后续业务请求可以用worker发送,内部走原生请求`,
2710
2710
  );
2711
2711
  this.businessWorkerReady = true;
2712
2712
  resolve(true);
2713
2713
  }
2714
2714
  }
2715
2715
 
2716
2716
  jdWorkerListenMsgData(workerData, thisTime,workerReadyState = true){
2717
2717
  if (window?.PAGE_DATA?.businessData?.workerLogEnable) {
2718
2718
  const getWorkerMsg = `【消息入口】收到jd worker发送的消息结果,时间为${thisTime},workerReady状态${workerReadyState},
2719
2719
  workerType为${workerData?.workerType},workerRequestIndex为${workerData?.workerRequestIndex},
2720
2720
  functionId是${workerData?.functionId}`
2721
2721
  console.info(getWorkerMsg,workerData);
2722
2722
  const {response, error,...otherData} = workerData
2723
2723
  draBusinessCustomReport({
2724
2724
  eventName: 'business',
2725
2725
  errorName: 'jd_worker_all_message_info',
2726
2726
  errorMessage: getWorkerMsg,
2727
2727
  extraData: JSON.stringify({
2728
2728
  workerData: otherData,
2729
2729
  response: typeof response,
2730
2730
  responseMsg: "如果返回response,比较大,不上报,error上报",
2731
2731
  error,
2732
2732
  workerReadyState,
2733
2733
  time: thisTime,
2734
2734
  }),
2735
2735
  });
2736
2736
  }
2737
2737
  if (workerData && workerData?.workerType) {
2738
2738
  const {
2739
2739
  functionId,
2740
2740
  postEndTime,
2741
2741
  postStartTime,
2742
2742
  originWorkerType,
2743
2743
  workerType,
2744
2744
  } = workerData;
2745
2745
  if (
2746
2746
  functionId &&
2747
2747
  originWorkerType === TaroEventType.jdWorkerPreRequest &&
2748
2748
  postStartTime &&
2749
2749
  postEndTime
2750
2750
  ) {
2751
2751
  const getMsg = `APP店铺业务worker请求返回结果成功,workerReady状态${workerReadyState},当前为${originWorkerType === workerType ?
2752
2752
  '预请求' :
2753
2753
  '第1次主动请求(因预请求在webview加载过程中未返回)'},functionId是${functionId},接口请求耗时${
2754
2754
  postEndTime - postStartTime
2755
2755
  }ms,接口传输到h5耗时${
2756
2756
  thisTime - postEndTime
2757
2757
  }ms,postStartTime为${postStartTime},postEndTime为${postEndTime},getResTime为${thisTime}`
2758
2758
  console.info(getMsg);
2759
2759
  draBusinessCustomLogReport(getMsg);
2760
2760
  }
2761
2761
  if (workerType === TaroEventType.jdWorkerPreRequest) {
2762
2762
  Taro.eventCenter.trigger(workerType, workerData);
2763
2763
  } else if (workerType === TaroEventType.jdWorkerRequest) {
2764
2764
  Taro.eventCenter.trigger(workerType, workerData);
2765
2765
  }else if(workerType === TaroEventType.jdWorkerMessage){
2766
2766
  console.info("收到jd worker发送的非接口消息,具体见数据",workerData)
2767
2767
  draBusinessCustomReport({
2768
2768
  eventName: 'business',
2769
2769
  errorName: 'jd_worker_only_message_info',
2770
2770
  errorMessage: `收到jd worker发送的非接口消息,具体见数据`,
2771
2771
  extraData: JSON.stringify({
2772
2772
  workerData,
2773
2773
  workerReadyState,
2774
2774
  time: thisTime,
2775
2775
  }),
2776
2776
  });
2777
2777
  }
2778
2778
  }
2779
2779
  }
2780
2780
 
2781
2781
  jdWorkerReadyPromise(): Promise<any> {
2782
2782
  if (isJdApp) {
2783
2783
  if (this.businessWorkerReady) {
2784
2784
  return Promise.resolve(true);
2785
2785
  } else {
2786
2786
  const getWorkerVersion = window?.PAGE_DATA?.businessData?.businessWorkerVersion
2787
2787
  const getOpenJdWorkerState =
2788
2788
  getWorkerVersion &&
2789
2789
  versionCompare(
2790
2790
  jdAppVersionStr,
2791
2791
  window?.shopGlobalSwitch?.jdAppWorkerOpenVersion || '15.3.10',
2792
2792
  ) >= 0;
2793
2793
  !this.businessWorkerReadyPromise &&
2794
2794
  (this.businessWorkerReadyPromise = getOpenJdWorkerState
2795
2795
  ? new Promise((resolve) => {
2796
2796
  this.jmfeReayPromise()
2797
2797
  .then(() => {
2798
2798
  window.jmfe
2799
2799
  .onMsgForWorker(
2800
2800
  { version_code: getWorkerVersion },
2801
2801
  (workerData) => {
2802
2802
  const getResTime = Date.now();
2803
2803
  this.jdWorkerListenMsgData(workerData, getResTime,this.businessWorkerReady)
2804
2804
  },
2805
2805
  )
2806
2806
  .then(() => {
2807
2807
  this.jdMarkWorkerReady(resolve, getWorkerVersion, "then")
2808
2808
  })
2809
2809
  .catch((error) => {
2810
2810
  if(!this.businessWorkerReady){
2811
2811
  console.info(
2812
2812
  `jd worker注册失败,版本为${getWorkerVersion},可能是客户端不支持worker,或者worker.js文件加载失败等原因。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑`,
2813
2813
  error,
2814
2814
  );
2815
2815
  draBusinessCustomReport({
2816
2816
  eventName: 'business',
2817
2817
  errorName: 'jmfe_onMsgForWorker_error',
2818
2818
  errorMessage: `jd worker注册失败,可能是客户端不支持worker,或者worker.js文件加载失败等原因。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑`,
2819
2819
  extraData: JSON.stringify({
2820
2820
  businessWorkerVersion: getWorkerVersion,
2821
2821
  error,
2822
2822
  time: Date.now(),
2823
2823
  }),
2824
2824
  });
2825
2825
  !window?.PAGE_DATA?.businessData
2826
2826
  ?.forbidJdWorkerErrorLoadApiSafeSteadyReay &&
2827
2827
  this.loadApiSafeSteadyReayPromise();
2828
2828
  resolve(false);
2829
2829
  }
2830
2830
  });
2831
2831
  })
2832
2832
  .catch((error) => {
2833
2833
  console.info('jmfe超时异常,worker注册失败', error);
2834
2834
  draBusinessCustomReport({
2835
2835
  eventName: 'business',
2836
2836
  errorName: 'jmfe_onMsgForWorker_error',
2837
2837
  errorMessage: `jd worker注册失败,原因是jmfe超时异常。h5需要在此处做逻辑兜底,无法通过worker处理单独逻辑`,
2838
2838
  extraData: JSON.stringify({
2839
2839
  businessWorkerVersion: getWorkerVersion,
2840
2840
  error,
2841
2841
  }),
2842
2842
  });
2843
2843
  !window?.PAGE_DATA?.businessData?.forbidJdWorkerErrorLoadApiSafeSteadyReay &&
2844
2844
  this.loadApiSafeSteadyReayPromise();
2845
2845
  resolve(false);
2846
2846
  });
2847
2847
  })
2848
2848
  : Promise.resolve(false));
2849
2849
  }
2850
2850
  return this.businessWorkerReadyPromise;
2851
2851
  } else {
2852
2852
  return Promise.resolve(false);
2853
2853
  }
2854
2854
  }
2855
2855
 
2856
2856
  taskTimeoutPromise(callBack, timeout = 2000) {
2857
2857
  return new Promise((resolve) => {
2858
2858
  setTimeout(
2859
2859
  () => {
2860
2860
  const getCallBackRes = typeof callBack === 'function' && callBack();
2861
2861
  return resolve(getCallBackRes || false);
2862
2862
  },
2863
2863
  isInJdAppH5DebugMode ? 0 : timeout,
2864
2864
  );
2865
2865
  });
2866
2866
  }
2867
2867
  _getJdPadMinWidthForListen() {
2868
2868
  return (
2869
2869
  isJdApp &&
2870
2870
  Math.min(window.screen.width, window.screen.height) >
2871
2871
  (window?.shopGlobalSwitch?.checkPadRootEleMinWidth || 600)
2872
2872
  );
2873
2873
  }
2874
2874
 
2875
2875
  getJdScreenSizeInfoPromise() {
2876
2876
  !this.jdScreenSizeInfoPromise &&
2877
2877
  (this.jdScreenSizeInfoPromise = new Promise((resolve) => {
2878
2878
  const getThisTime = Date.now();
2879
2879
  this.jmfeReayPromise().then(() => {
2880
2880
  return Promise.race([
2881
2881
  window.jmfe.getScreenSize(),
2882
2882
  this.taskTimeoutPromise(() => {
2883
2883
  return {
2884
2884
  status: '-10',
2885
2885
  msg: '获取大屏信息2s超时',
2886
2886
  };
2887
2887
  }),
2888
2888
  ])
2889
2889
  .then((res) => {
2890
2890
  console.warn('===获取app大屏信息====', res);
2891
2891
  const { status, data } = res;
2892
2892
  if (status === '0' && data) {
2893
2893
  const { sizeType, isLandscape, pageHeight, pageWidth } = data;
2894
2894
  const getPageInfo = dealNativePixelToCssPixel({
2895
2895
  pageWidth,
2896
2896
  pageHeight,
2897
2897
  });
2898
2898
  this.info.sysInfo.jdScreenSizeType = sizeType;
2899
2899
  const getUseTime = Date.now() - getThisTime;
2900
2900
  console.warn(
2901
2901
  '===计算是否是app大屏信息,需满足宽度最新720===',
2902
2902
  getPageInfo,
2903
2903
  '原始数据',
2904
2904
  data,
2905
2905
  '是否是横屏isLandscape为1=',
2906
2906
  isLandscape,
2907
2907
  '用时',
2908
2908
  getUseTime,
2909
2909
  );
2910
2910
  if (getPageInfo?.pageWidth > 0) {
2911
2911
  this.rootEleInitWidth = getPageInfo?.pageWidth;
2912
2912
  draBusinessCustomReport({
2913
2913
  eventName: 'UIInteract',
2914
2914
  errorName: 'rootEle_width_getJdScreenSizeInfo',
2915
2915
  errorMessage: `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果,用时${getUseTime}`,
2916
2916
  extraData: JSON.stringify({
2917
2917
  isJdApp,
2918
2918
  getPageInfo,
2919
2919
  originData: res,
2920
2920
  }),
2921
2921
  });
2922
2922
  resolve(getPageInfo);
2923
2923
  } else {
2924
2924
  resolve({
2925
2925
  pageWidth: 0,
2926
2926
  pageHeight: 0,
2927
2927
  msg: '转换异常',
2928
2928
  });
2929
2929
  }
2930
2930
  } else {
2931
2931
  resolve({
2932
2932
  pageWidth: 0,
2933
2933
  pageHeight: 0,
2934
2934
  msg: '获取大屏信息异常或者超时',
2935
2935
  });
2936
2936
  }
2937
2937
  })
2938
2938
  .catch((err) => {
2939
2939
  console.log('获取大屏信息异常', err);
2940
2940
  resolve({
2941
2941
  pageWidth: 0,
2942
2942
  pageHeight: 0,
2943
2943
  msg: '获取大屏信息异常',
2944
2944
  });
2945
2945
  });
2946
2946
  });
2947
2947
  }));
2948
2948
  return this.jdScreenSizeInfoPromise;
2949
2949
  }
2950
2950
 
2951
2951
  listenJdTabletScreenChange() {
2952
2952
  this.jmfeReayPromise().then(() => {
2953
2953
  try {
2954
2954
  console.log('初始化监听大屏信息变化', window.jmfe.listenDeviceScreenChange);
2955
2955
  window.jmfe.listenDeviceScreenChange((event) => {
2956
2956
  console.log(
2957
2957
  '监听app大屏信息变化,orientation为landscape表示横屏,multiScreen为1表示android端分屏',
2958
2958
  event,
2959
2959
  '通过前端判断是不是横屏',
2960
2960
  window.matchMedia('(orientation: landscape)')?.matches,
2961
2961
  );
2962
2962
  const { orientation } = event?.data;
2963
2963
  if (orientation) {
2964
2964
  this.info.sysInfo.isJdTabletLandscape = orientation === 'landscape';
2965
2965
  Taro.eventCenter.trigger(
2966
2966
  TaroEventType.TABLE_SCREEN_CHANGE,
2967
2967
  this.info.sysInfo.isJdTabletLandscape,
2968
2968
  orientation,
2969
2969
  );
2970
2970
  }
2971
2971
  });
2972
2972
  } catch (error) {
2973
2973
  console.log('listenScreenChange的打印error:', error);
2974
2974
  }
2975
2975
  });
2976
2976
  }
2977
2977
 
2978
2978
  updateBusinessDomainAndApi(domain, api) {
2979
2979
  }
2980
2980
 
2981
2981
  formatNativeScreenPageData(action) {
2982
2982
  let getChangePageInfo: any = null;
2983
2983
  try {
2984
2984
  const getNativeScreenPageInfoStr = window.XWebView?._callNative(
2985
2985
  JSON.stringify({
2986
2986
  plugin: 'JDHybridScreenPlugin',
2987
2987
  action,
2988
2988
  sync: '1',
2989
2989
  }),
2990
2990
  );
2991
2991
  const getChangePageInfoData =
2992
2992
  typeof getNativeScreenPageInfoStr === 'string'
2993
2993
  ? JSON.parse(getNativeScreenPageInfoStr)
2994
2994
  : null;
2995
2995
  if (getChangePageInfoData && typeof getChangePageInfoData === 'object') {
2996
2996
  const { code, data } = getChangePageInfoData;
2997
2997
  getChangePageInfo = code && code === '0' ? data : null;
2998
2998
  }
2999
2999
  } catch (e) {
3000
3000
  console.log('JDHybridScreenPlugin转换异常', e);
3001
3001
  }
3002
3002
  return getChangePageInfo;
3003
3003
  }
3004
3004
 
3005
3005
  isAndroidFoldScreen() {
3006
3006
  return this.formatNativeScreenPageData('isFoldScreen') === '1';
3007
3007
  }
3008
3008
 
3009
3009
  isHarmonyFoldScreenPromise(): Promise<{
3010
3010
  isFoldScreen: boolean;
3011
3011
  getFoldDisplayMode?: number;
3012
3012
  }> {
3013
3013
  return new Promise((resolve) => {
3014
3014
  this.jmfeReayPromise()
3015
3015
  .then(() => {
3016
3016
  if (window.jmfe?.callNative) {
3017
3017
  Promise.all([
3018
3018
  window.jmfe.callNative('JDHybridScreenPlugin', 'isFoldScreen', {}),
3019
3019
  window.jmfe.callNative('JDHybridScreenPlugin', 'getFoldDisplayMode', {}),
3020
3020
  ])
3021
3021
  .then((res) => {
3022
3022
  resolve({
3023
3023
  isFoldScreen: res?.[0]?.data === '1',
3024
3024
  getFoldDisplayMode: res?.[1]?.data,
3025
3025
  });
3026
3026
  })
3027
3027
  .catch(() => {
3028
3028
  resolve({
3029
3029
  isFoldScreen: false,
3030
3030
  getFoldDisplayMode: undefined,
3031
3031
  });
3032
3032
  });
3033
3033
  } else {
3034
3034
  resolve({
3035
3035
  isFoldScreen: false,
3036
3036
  getFoldDisplayMode: undefined,
3037
3037
  });
3038
3038
  }
3039
3039
  })
3040
3040
  .catch(() => {
3041
3041
  resolve({
3042
3042
  isFoldScreen: false,
3043
3043
  getFoldDisplayMode: undefined,
3044
3044
  });
3045
3045
  });
3046
3046
  });
3047
3047
  }
3048
3048
 
3049
3049
  getJdAndroidPageChangeScreenInfo() {
3050
3050
  const getPageScreenInfo = this.formatNativeScreenPageData('getScreenSize');
3051
3051
  if (getPageScreenInfo && getPageScreenInfo?.pageWidth && getPageScreenInfo?.pageHeight) {
3052
3052
  const { pageWidth, pageHeight } = dealNativePixelToCssPixel({
3053
3053
  pageWidth: getPageScreenInfo.pageWidth,
3054
3054
  pageHeight: getPageScreenInfo.pageHeight,
3055
3055
  });
3056
3056
  getPageScreenInfo.pageWidth = pageWidth;
3057
3057
  getPageScreenInfo.pageHeight = pageHeight;
3058
3058
  }
3059
3059
  return getPageScreenInfo;
3060
3060
  }
3061
3061
 
3062
3062
  getRootEleWindowWidthInfo() {
3063
3063
  const getRootEleWidth = document.documentElement.getBoundingClientRect().width;
3064
3064
  const getWindowWidth = window.innerWidth;
3065
3065
  const getScreenWidth = window.screen.width;
3066
3066
  return {
3067
3067
  getRootEleWidth,
3068
3068
  getWindowWidth,
3069
3069
  getScreenWidth,
3070
3070
  };
3071
3071
  }
3072
3072
 
3073
3073
  dealRootEleWidthFn(reportParam = {}, timeout = 0) {
3074
3074
  const { getRootEleWidth, getWindowWidth, getScreenWidth } = this.getRootEleWindowWidthInfo();
3075
3075
  console.log(
3076
3076
  '当前获取根元素的宽度',
3077
3077
  getRootEleWidth,
3078
3078
  'getWindowWidth',
3079
3079
  getWindowWidth,
3080
3080
  'getScreenWidth',
3081
3081
  getScreenWidth,
3082
3082
  );
3083
3083
  const getLastWidth =
3084
3084
  getRootEleWidth > 0
3085
3085
  ? Math.round(getRootEleWidth)
3086
3086
  : Math.round(getWindowWidth > 0 ? getWindowWidth : getScreenWidth);
3087
3087
  console.warn(
3088
3088
  `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果超时,超时时间超时时间${timeout}ms,最终兜底再获取一次根元素宽度${getLastWidth}`,
3089
3089
  );
3090
3090
  timeout > 0 &&
3091
3091
  draBusinessCustomReport({
3092
3092
  eventName: 'UIInteract',
3093
3093
  errorName: 'rootEle_width_timeout_getJdScreenSizeInfo',
3094
3094
  errorMessage: `根元素获取宽度初始化为0,通过getJdScreenSizeInfo获取结果超时,超时时间${timeout}ms,最终兜底再获取一次根元素宽度${getLastWidth}`,
3095
3095
  extraData: JSON.stringify({
3096
3096
  isJdApp,
3097
3097
  getRootEleWidth,
3098
3098
  getWindowWidth,
3099
3099
  getScreenWidth,
3100
3100
  ...reportParam,
3101
3101
  }),
3102
3102
  });
3103
3103
  return getLastWidth;
3104
3104
  }
3105
3105
 
3106
3106
  getPadWindowRootEleWidthPromise() {
3107
3107
  if (this.rootEleInitWidth > 0) {
3108
3108
  return Promise.resolve(this.rootEleInitWidth);
3109
3109
  } else {
3110
3110
  !this.rootEleWidthRegisterPromise &&
3111
3111
  (this.rootEleWidthRegisterPromise = new Promise((resolve) => {
3112
3112
  const getRootEleInitWidth = this.getRootEleWindowWidthInfo().getRootEleWidth;
3113
3113
  if (getRootEleInitWidth > 0) {
3114
3114
  console.log('初始化获取根元素宽度正常,为', getRootEleInitWidth);
3115
3115
  this.rootEleInitWidth = Math.round(getRootEleInitWidth);
3116
3116
  resolve(this.rootEleInitWidth);
3117
3117
  } else {
3118
3118
  const timerPromise = () => {
3119
3119
  return new Promise((resolve2) => {
3120
3120
  window.setTimeout(() => {
3121
3121
  const { getRootEleWidth, getWindowWidth, getScreenWidth } =
3122
3122
  this.getRootEleWindowWidthInfo();
3123
3123
  if (getRootEleWidth > 0 || getWindowWidth > 0) {
3124
3124
  console.warn(
3125
3125
  `根元素获取宽度初始化为0,200ms后尝试获取最新结果,getRootEleWidth为${getRootEleWidth},getWindowWidth为${getWindowWidth},getScreenWidth为${getScreenWidth}`,
3126
3126
  );
3127
3127
  draBusinessCustomReport({
3128
3128
  eventName: 'UIInteract',
3129
3129
  errorName: 'rootEle_width_200_timeout_info',
3130
3130
  errorMessage: `根元素获取宽度初始化为0,200ms后尝试获取最新结果,getRootEleWidth为${getRootEleWidth},getWindowWidth为${getWindowWidth}`,
3131
3131
  extraData: JSON.stringify({
3132
3132
  isJdApp,
3133
3133
  getRootEleWidth,
3134
3134
  getWindowWidth,
3135
3135
  getScreenWidth,
3136
3136
  }),
3137
3137
  });
3138
3138
  const getRes =
3139
3139
  getRootEleWidth > 0 && getWindowWidth > 0
3140
3140
  ? Math.min(getRootEleWidth, getWindowWidth)
3141
3141
  : Math.max(getRootEleWidth, getWindowWidth);
3142
3142
  resolve2({
3143
3143
  pageWidth: Math.round(getRes),
3144
3144
  });
3145
3145
  }
3146
3146
  }, 200);
3147
3147
  });
3148
3148
  };
3149
3149
  Promise.race([timerPromise(), this.getJdScreenSizeInfoPromise()]).then((res) => {
3150
3150
  const { pageWidth } = res;
3151
3151
  console.log('获取结果Promise.race getJdScreenSizeInfo', res);
3152
3152
  pageWidth > 0 ? resolve(pageWidth) : resolve(this.dealRootEleWidthFn(res, 2000));
3153
3153
  });
3154
3154
  }
3155
3155
  }));
3156
3156
  return this.rootEleWidthRegisterPromise;
3157
3157
  }
3158
3158
  }
3159
3159
 
3160
3160
  async getSystemInfo(params) {
3161
3161
  const getParams = Object.assign({}, params || {});
3162
3162
  if (this.rootEleInitWidth > 0) {
3163
3163
  getParams['rootEleInitWidth'] = this.rootEleInitWidth;
3164
3164
  console.log('获取当前系统信息的时候已经获取到根元素宽度,值为', this.rootEleInitWidth);
3165
3165
  } else {
3166
3166
  if (this._getJdPadMinWidthForListen()) {
3167
3167
  getParams['rootEleInitWidth'] = await this.getPadWindowRootEleWidthPromise();
3168
3168
  getParams['replaceSystemWidth'] = true;
3169
3169
  }
3170
3170
  }
3171
3171
  isJdApp && this.createLanguagePromise();
3172
3172
  let info: UtilsInterFace.taroGetSystemInfoSyncRes | any = getSystemInfos(getParams);
3173
3173
  if (isJdAndAndroidDevice && info?.initWindowWidth <= 0) {
3174
3174
  let _isfoldScreen = false;
3175
3175
  const getStorageData = getTaroStorageKeyValue('jd_shopx_androidIsFoldScreen');
3176
3176
  console.info(
3177
3177
  '获取当前本地存储是否有jd_shopx_androidIsFoldScreen',
3178
3178
  getStorageData,
3179
3179
  '通过缓存值第一次判断是否是折叠屏',
3180
3180
  getStorageData === 'true',
3181
3181
  );
3182
3182
  if (!getStorageData) {
3183
3183
  _isfoldScreen = this.isAndroidFoldScreen();
3184
3184
  setTaroStorage('jd_shopx_androidIsFoldScreen', `${_isfoldScreen}`);
3185
3185
  } else {
3186
3186
  _isfoldScreen = getStorageData === 'true';
3187
3187
  }
3188
3188
  if (_isfoldScreen) {
3189
3189
  const getJdAndroidPageInfo = this.getJdAndroidPageChangeScreenInfo();
3190
3190
  if (getJdAndroidPageInfo) {
3191
3191
  info = getSystemInfos(getJdAndroidPageInfo);
3192
3192
  console.warn(
3193
3193
  '当前为松果安卓折叠屏app,获取折叠屏信息',
3194
3194
  getJdAndroidPageInfo,
3195
3195
  '获取转换后的系统信息',
3196
3196
  info,
3197
3197
  );
3198
3198
  draBusinessCustomReport({
3199
3199
  eventName: 'UIInteract',
3200
3200
  errorName: 'android_jdapp_foldScreen_info',
3201
3201
  errorMessage:
3202
3202
  '松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异',
3203
3203
  extraData: JSON.stringify({
3204
3204
  title: `松果安卓app为折叠屏,重置获取的系统宽高信息,因为获取宽高度信息初始化内部可能存在横竖屏差异`,
3205
3205
  androidPageInfo: getJdAndroidPageInfo,
3206
3206
  jdAppVersionStr,
3207
3207
  taroSysInfo: info,
3208
3208
  }),
3209
3209
  });
3210
3210
  }
3211
3211
  }
3212
3212
  }
3213
3213
  if (isJdApp) {
3214
3214
  info?.isJdTabletDevice && this.listenJdTabletScreenChange();
3215
3215
  }
3216
3216
  this.info.sysInfo = {
3217
3217
  actualNavBarHeight: 0,
3218
3218
  ...this.info.sysInfo,
3219
3219
  ...info,
3220
3220
  safeContentHeight: info?.screenHeight,
3221
3221
  headerHeight: 0,
3222
3222
  tabBarHeight: 0,
3223
3223
  languageType: languageNowType,
3224
3224
  };
3225
3225
  if (isJdApp || isH5AndJingGouMini) {
3226
3226
  this.getAddressCachePromise();
3227
3227
  this.getLbsAddressCachePromise();
3228
3228
  }
3229
3229
  if (isJdApp) {
3230
3230
  this.info.sysInfo['hostVersionName'] = jdAppVersionStr;
3231
3231
  this.info.sysInfo['hostAppVersion'] = jdAppVersion;
3232
3232
  this.getJdAppBaseInfo();
3233
3233
  this.getElderModePromise();
3234
3234
  this.getJDAppearanceStatePromise();
3235
3235
  this.createJdAndroidRquestEventForTouchStart();
3236
3236
  }
3237
3237
  this.getWifiVideoAutoPlayAsync();
3238
3238
  this.getMPaasConfigAsync();
3239
3239
  this.getNetWorkType();
3240
3240
  }
3241
3241
 
3242
3242
  getElderModePromise() {
3243
3243
  if (this.info.sysInfo.hasOwnProperty('jdAppModeType')) {
3244
3244
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
3245
3245
  } else {
3246
3246
  if (isJdAndAndroidDevice) {
3247
3247
  this.info.sysInfo.jdAppModeType = '0';
3248
3248
  return Promise.resolve(this.info.sysInfo.jdAppModeType);
3249
3249
  } else {
3250
3250
  return Promise.race([
3251
3251
  this.taskTimeoutPromise(() => {
3252
3252
  this.info.sysInfo.jdAppModeType = '0';
3253
3253
  return this.info.sysInfo.jdAppModeType;
3254
3254
  }),
3255
3255
  new Promise((resolve) => {
3256
3256
  const getCallBackName = `getJdCurrentModeType${Date.now()}`;
3257
3257
  if (!window[getCallBackName]) {
3258
3258
  window[getCallBackName] = (res) => {
3259
3259
  try {
3260
3260
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
3261
3261
  const { status, data, msg } = getResJson;
3262
3262
  console.log(`获取松果app展示模式成功,返回结果${data}`);
3263
3263
  if (status === '0') {
3264
3264
  this.info.sysInfo.jdAppModeType = data;
3265
3265
  resolve(data);
3266
3266
  } else {
3267
3267
  resolve('0');
3268
3268
  }
3269
3269
  } catch (e) {
3270
3270
  resolve('0');
3271
3271
  }
3272
3272
  window[getCallBackName] = null;
3273
3273
  };
3274
3274
  }
3275
3275
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
3276
3276
  method: 'callSyncRouterModuleWithParams',
3277
3277
  params: JSON.stringify({
3278
3278
  routerURL: 'router://JDBModeModule/getCurrentMode',
3279
3279
  routerParam: {},
3280
3280
  callBackName: `window.${getCallBackName}`,
3281
3281
  callBackId: `${getCallBackName}Ios`,
3282
3282
  }),
3283
3283
  });
3284
3284
  }),
3285
3285
  ]);
3286
3286
  }
3287
3287
  }
3288
3288
  }
3289
3289
  getAPPUseStraightCorner() {
3290
3290
  const routerURL = 'router://JDBaseUtilsModule/isUI14Enable';
3291
3291
  const params = {
3292
3292
  routerURL,
3293
3293
  routerParam: {},
3294
3294
  jdRouter: '1',
3295
3295
  };
3296
3296
  if (this.info.sysInfo.hasOwnProperty('jdStraightCorner')) {
3297
3297
  return Promise.resolve(this.info.sysInfo.jdStraightCorner);
3298
3298
  } else {
3299
3299
  return this.jmfeReayPromise()
3300
3300
  .then(() => {
3301
3301
  if (isJdAndHarmonyDevice || !isJdApp) {
3302
3302
  console.log('not APP or is Harmony');
3303
3303
  return Promise.resolve(false);
3304
3304
  }
3305
3305
  console.log('jmfe setShareInfo', params);
3306
3306
  return Promise.race([
3307
3307
  window.jmfe.callRouter(params),
3308
3308
  this.taskTimeoutPromise(() => {
3309
3309
  return false;
3310
3310
  }),
3311
3311
  ]).then(({ status, data }) => {
3312
3312
  console.log('004 ~ file: index.tsx:133 ~ .then ~ data:', data);
3313
3313
  console.log('004 ~ file: index.tsx:133 ~ .then ~ status:', status);
3314
3314
  this.info.sysInfo.jdStraightCorner = status === '0' && Number(data) === 1;
3315
3315
  return Promise.resolve(status === '0' && Number(data) === 1);
3316
3316
  });
3317
3317
  })
3318
3318
  .catch((e) => {
3319
3319
  console.log('jmfe error', e);
3320
3320
  return Promise.resolve(false);
3321
3321
  });
3322
3322
  }
3323
3323
  }
3324
3324
 
3325
3325
  getJDAppearanceStatePromise() {
3326
3326
  if (this.info.sysInfo.hasOwnProperty('jdAppearanceState')) {
3327
3327
  return Promise.resolve(this.info.sysInfo.jdAppearanceState);
3328
3328
  } else {
3329
3329
  return Promise.race([
3330
3330
  this.taskTimeoutPromise(() => {
3331
3331
  this.info.sysInfo.jdAppearanceState = '0';
3332
3332
  return this.info.sysInfo.jdAppearanceState;
3333
3333
  }),
3334
3334
  new Promise((resolve) => {
3335
3335
  const getCallBackName = `getJdCurrentAppearanceState${Date.now()}`;
3336
3336
  if (!window[getCallBackName]) {
3337
3337
  window[getCallBackName] = (res) => {
3338
3338
  try {
3339
3339
  console.log('getJDAppearanceStatePromise', res);
3340
3340
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
3341
3341
  const { status, data, msg } = getResJson;
3342
3342
  console.log(`获取松果app是否开启黑暗模式成功,返回结果${data}`);
3343
3343
  if (status === '0') {
3344
3344
  this.info.sysInfo.jdAppearanceState = data;
3345
3345
  resolve(data);
3346
3346
  } else {
3347
3347
  resolve('0');
3348
3348
  }
3349
3349
  } catch (e) {
3350
3350
  resolve('0');
3351
3351
  }
3352
3352
  window[getCallBackName] = null;
3353
3353
  };
3354
3354
  }
3355
3355
  if (isAndroidDevice) {
3356
3356
  const jsonString = JSON.stringify({
3357
3357
  callBackName: `window.${getCallBackName}`,
3358
3358
  });
3359
3359
  console.log('window.JDAppearance', window?.JDAppearance);
3360
3360
  window?.JDAppearance &&
3361
3361
  window?.JDAppearance?.getUiState &&
3362
3362
  window.JDAppearance.getUiState(jsonString);
3363
3363
  } else {
3364
3364
  window?.webkit?.messageHandlers?.JDAppUnite?.postMessage({
3365
3365
  method: 'callSyncRouterModuleWithParams',
3366
3366
  params: JSON.stringify({
3367
3367
  routerURL: 'router://JDWebViewBusinessModule/getJDAppearanceState',
3368
3368
  routerParam: {},
3369
3369
  callBackName: `window.${getCallBackName}`,
3370
3370
  callBackId: `${getCallBackName}Ios`,
3371
3371
  }),
3372
3372
  });
3373
3373
  }
3374
3374
  }),
3375
3375
  ]);
3376
3376
  }
3377
3377
  }
3378
3378
 
3379
3379
  createJdAndroidRquestEventForTouchStart() {
3380
3380
  if (isJdAndAndroidDevice && window?.JdAndroid) {
3381
3381
  const rootEleNode = document.querySelector('body');
3382
3382
  if (rootEleNode) {
3383
3383
  rootEleNode.addEventListener('touchstart', this.jdAndroidAddEventListenerTouchStart, false);
3384
3384
  }
3385
3385
  }
3386
3386
  }
3387
3387
  jdAndroidAddEventListenerTouchStart(e) {
3388
3388
  const isH5SwiperCustomEle = e?.target?.closest('.J_h5SwiperCustom');
3389
3389
  if (!isH5SwiperCustomEle && window?.JdAndroid) {
3390
3390
  const hasCustomEle = e
3391
3391
  ? e?.target?.closest('.J_customScroll') || e?.target?.closest('.J_customLayout')
3392
3392
  : false;
3393
3393
  if (!hasCustomEle) {
3394
3394
  window?.JdAndroid?.requestEvent && window.JdAndroid.requestEvent(false);
3395
3395
  console.log(
3396
3396
  'createJdAndroidRquestEvent 所有松果安卓APP内的document touch start事件执行检测requestEvent并重置为false',
3397
3397
  );
3398
3398
  }
3399
3399
  }
3400
3400
  }
3401
3401
  removeJdAndroidRquestEventForTouchStart() {
3402
3402
  if (isJdAndAndroidDevice && window.JdAndroid) {
3403
3403
  const rootEleNode = document.querySelector('body');
3404
3404
  if (rootEleNode) {
3405
3405
  rootEleNode.removeEventListener(
3406
3406
  'touchstart',
3407
3407
  this.jdAndroidAddEventListenerTouchStart,
3408
3408
  false,
3409
3409
  );
3410
3410
  }
3411
3411
  }
3412
3412
  }
3413
3413
 
3414
3414
  getNetWorkType() {
3415
3415
  if (isJdApp) {
3416
3416
  return new Promise((resolve) => {
3417
3417
  this.jmfeReayPromise().then(() => {
3418
3418
  window.jmfe
3419
3419
  .getNetworkStatus()
3420
3420
  .then(({ status, data }) => {
3421
3421
  console.log('在app内初始化通过jmfe对象获取网络状态完成,当前网络状态====', data);
3422
3422
  if (status === '0') {
3423
3423
  this.info.sysInfo['networkType'] = data;
3424
3424
  resolve({
3425
3425
  networkType: data,
3426
3426
  });
3427
3427
  } else {
3428
3428
  return this._taroGetNetworkType();
3429
3429
  }
3430
3430
  })
3431
3431
  .catch((err) => {
3432
3432
  console.log('在app内初始化通过jmfe对象获取网络状态异常====', err);
3433
3433
  return this._taroGetNetworkType();
3434
3434
  });
3435
3435
  });
3436
3436
  });
3437
3437
  } else {
3438
3438
  return this._taroGetNetworkType();
3439
3439
  }
3440
3440
  }
3441
3441
  _taroGetNetworkType() {
3442
3442
  return Taro.getNetworkType().then((getRes) => {
3443
3443
  if (getRes && getRes.networkType) {
3444
3444
  this.info.sysInfo['netWorkType'] = getRes.networkType;
3445
3445
  console.log(
3446
3446
  '在app内通过taro对象获取网络状态完成,当前网络状态',
3447
3447
  this.info.sysInfo['netWorkType'],
3448
3448
  );
3449
3449
  }
3450
3450
  return getRes;
3451
3451
  });
3452
3452
  }
3453
3453
 
3454
3454
  getJdAppBaseInfo() {
3455
3455
  const appKeyCacheToCookieMinuteTime =
3456
3456
  window?.shopGlobalSwitch?.appKeyCacheToCookieMinuteTime || 0,
3457
3457
  appUuidCacheToCookieMinuteTime =
3458
3458
  window?.shopGlobalSwitch?.appUuidCacheToCookieMinuteTime || 0,
3459
3459
  getAppKey = cookie.get(cacheAppKey),
3460
3460
  getAppUuidKey = cookie.get(cacheAppUuidKey);
3461
3461
  console.log(
3462
3462
  '在app内初始化优先通过cookie获取api请求参数集合baseApiKeyParam',
3463
3463
  cacheAppKey,
3464
3464
  getAppKey,
3465
3465
  cacheAppUuidKey,
3466
3466
  getAppUuidKey,
3467
3467
  );
3468
3468
  if (
3469
3469
  appKeyCacheToCookieMinuteTime &&
3470
3470
  appUuidCacheToCookieMinuteTime &&
3471
3471
  getAppKey &&
3472
3472
  getAppUuidKey
3473
3473
  ) {
3474
3474
  const [uuid, eufv] = getAppUuidKey.split('@');
3475
3475
  const baseApiKeyParam = {
3476
3476
  uuid,
3477
3477
  };
3478
3478
  getAppKey !== '-1000' && (baseApiKeyParam['x_app_key'] = getAppKey);
3479
3479
  if (eufv === '1' && /-/.test(uuid)) {
3480
3480
  const [eu, fv] = uuid.split('-');
3481
3481
  baseApiKeyParam['eu'] = eu;
3482
3482
  baseApiKeyParam['fv'] = fv;
3483
3483
  }
3484
3484
  this.info.sysInfo['baseApiKeyParam'] = baseApiKeyParam;
3485
3485
  this.jmfeReayPromise().then(() => {
3486
3486
  console.log('在app内初始化通过cookie获取api请求参数集合baseApiKeyParam', baseApiKeyParam);
3487
3487
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, baseApiKeyParam);
3488
3488
  });
3489
3489
  } else {
3490
3490
  const checkGetJdAppKeyState =
3491
3491
  window?.shopGlobalSwitch?.getJdAppKeyVersion &&
3492
3492
  jdAppVersionCompare(window?.shopGlobalSwitch?.getJdAppKeyVersion) >= 0;
3493
3493
  this.jmfeReayPromise().then(() => {
3494
3494
  Promise.all([
3495
3495
  checkGetJdAppKeyState && window.jmfe?.callNative
3496
3496
  ? window.jmfe.callNative('SwitchQueryPlugin', 'getAppKey', {}, '0')
3497
3497
  : Promise.resolve({
3498
3498
  status: '-1000',
3499
3499
  msg: '当前版本不支持获取松果app中的getAppKey',
3500
3500
  data: '-1000',
3501
3501
  }),
3502
3502
  window.jmfe.getDeviceInfo(),
3503
3503
  ]).then((resList) => {
3504
3504
  const [getAppKeyRes, deviceInfoRes] = resList;
3505
3505
  console.log(
3506
3506
  '在app内初始化通过jmfe获取getAppKey结果',
3507
3507
  getAppKeyRes,
3508
3508
  '通过jmfe获取getDeviceInfo获取结果',
3509
3509
  deviceInfoRes,
3510
3510
  );
3511
3511
  const baseApiKeyParam = {};
3512
3512
  if (['0', '-1000'].includes(getAppKeyRes?.status) && getAppKeyRes?.data) {
3513
3513
  const getJmfeAppKey = getAppKeyRes?.data;
3514
3514
  if (getJmfeAppKey && getJmfeAppKey !== '') {
3515
3515
  getJmfeAppKey !== '-1000' && (baseApiKeyParam['x_app_key'] = getJmfeAppKey);
3516
3516
  const getJdAppKeyCacheToCookieMinuteTime =
3517
3517
  (window?.shopGlobalSwitch?.appKeyCacheToCookieMinuteTime || 0) * 60 * 1000;
3518
3518
  if (getJdAppKeyCacheToCookieMinuteTime) {
3519
3519
  const expires = new Date(Date.now() + getJdAppKeyCacheToCookieMinuteTime);
3520
3520
  cookie.set(cacheAppKey, getJmfeAppKey, {
3521
3521
  path: '/',
3522
3522
  expires,
3523
3523
  });
3524
3524
  }
3525
3525
  }
3526
3526
  }
3527
3527
  if (deviceInfoRes?.status === '0' && deviceInfoRes?.data) {
3528
3528
  const { uuid, eufv = '0', networkType } = deviceInfoRes?.data;
3529
3529
  if (uuid && uuid !== '') {
3530
3530
  networkType && (this.info.sysInfo['netWorkType'] = networkType);
3531
3531
  baseApiKeyParam['uuid'] = uuid;
3532
3532
  if (eufv === '1' && /-/.test(uuid)) {
3533
3533
  const [eu, fv] = uuid.split('-');
3534
3534
  baseApiKeyParam['eu'] = eu;
3535
3535
  baseApiKeyParam['fv'] = fv;
3536
3536
  }
3537
3537
  const getAppUuidCacheToCookieMinuteTime =
3538
3538
  (window?.shopGlobalSwitch?.appUuidCacheToCookieMinuteTime || 0) * 60 * 1000;
3539
3539
  if (getAppUuidCacheToCookieMinuteTime) {
3540
3540
  const expires = new Date(Date.now() + getAppUuidCacheToCookieMinuteTime);
3541
3541
  cookie.set(cacheAppUuidKey, `${uuid}@${eufv}`, {
3542
3542
  path: '/',
3543
3543
  expires,
3544
3544
  });
3545
3545
  }
3546
3546
  }
3547
3547
  }
3548
3548
  console.log(
3549
3549
  '在app内初始化通过jmfe需要更新的基础api请求参数集合baseApiKeyParam',
3550
3550
  baseApiKeyParam,
3551
3551
  );
3552
3552
  if (Object.keys(baseApiKeyParam).length > 0) {
3553
3553
  this.info.sysInfo['baseApiKeyParam'] = baseApiKeyParam;
3554
3554
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, baseApiKeyParam);
3555
3555
  }
3556
3556
  });
3557
3557
  });
3558
3558
  }
3559
3559
  }
3560
3560
 
3561
3561
  getCacheAddressRouter() {
3562
3562
  if (isJdApp) {
3563
3563
  if (!isJdAndHarmonyDevice) {
3564
3564
  return Promise.race([
3565
3565
  new Promise((resolve) => {
3566
3566
  const getCallBackName = `getJdCacheAddress${Date.now()}`;
3567
3567
  if (!window[getCallBackName]) {
3568
3568
  window[getCallBackName] = (res) => {
3569
3569
  console.warn(`获取松果appGetJdCacheAddressRes,返回结果`, res);
3570
3570
  try {
3571
3571
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
3572
3572
  resolve(getResJson);
3573
3573
  } catch (e) {
3574
3574
  resolve({
3575
3575
  status: '-1002',
3576
3576
  msg: '地址信息解析json异常',
3577
3577
  res,
3578
3578
  });
3579
3579
  }
3580
3580
  window[getCallBackName] = null;
3581
3581
  };
3582
3582
  }
3583
3583
  const getRouterParam = {
3584
3584
  sceneId: 'basicShoppingProcess',
3585
3585
  };
3586
3586
  if (isAndroidDevice) {
3587
3587
  return callRouterAndroid({
3588
3588
  routerURL: 'router://JDAddressModule/getCacheAddress',
3589
3589
  routerParam: getRouterParam,
3590
3590
  callBackName: getCallBackName,
3591
3591
  isSync: true,
3592
3592
  });
3593
3593
  } else {
3594
3594
  return callRouterIOS({
3595
3595
  routerURL: 'router://JDBAddressCacheManagerModule/getCacheAddress',
3596
3596
  routerParam: getRouterParam,
3597
3597
  callBackName: getCallBackName,
3598
3598
  });
3599
3599
  }
3600
3600
  }),
3601
3601
  this.taskTimeoutPromise(() => {
3602
3602
  return {
3603
3603
  status: '-1000',
3604
3604
  msg: '原生router协议获取地址信息超时',
3605
3605
  };
3606
3606
  }, 3000),
3607
3607
  ]);
3608
3608
  } else {
3609
3609
  return Promise.race([
3610
3610
  new Promise((resolve) => {
3611
3611
  this.jmfeReayPromise()
3612
3612
  .then(() => {
3613
3613
  const plugin = 'JDHybridRouterPlugin';
3614
3614
  const action = 'callSyncRouterModuleWithParams';
3615
3615
  const params = {
3616
3616
  routerURL: 'router://JDAddressCacheModule/getAddressCache?sceneId=1',
3617
3617
  routerParam: '',
3618
3618
  };
3619
3619
  const sync = '1';
3620
3620
  try {
3621
3621
  window.jmfe.callNative(plugin, action, params, sync).then((res) => {
3622
3622
  resolve(res);
3623
3623
  });
3624
3624
  } catch (error) {
3625
3625
  resolve({
3626
3626
  status: '-1001',
3627
3627
  msg: '判断jmfe不存在,获取经纬度信息异常',
3628
3628
  });
3629
3629
  }
3630
3630
  })
3631
3631
  .catch(() => {
3632
3632
  resolve({
3633
3633
  status: '-1002',
3634
3634
  msg: '鸿蒙系统调用jmfe异常,获取失败',
3635
3635
  });
3636
3636
  });
3637
3637
  }),
3638
3638
  this.taskTimeoutPromise(() => {
3639
3639
  return {
3640
3640
  status: '-1000',
3641
3641
  msg: '原生router协议获取地址信息超时',
3642
3642
  };
3643
3643
  }, 3000),
3644
3644
  ]);
3645
3645
  }
3646
3646
  } else if (isH5AndJingGouMini) {
3647
3647
  const { areaId, addressName } = this.getJingGouMiniInh5Address();
3648
3648
  if (areaId && areaId !== '' && addressName && addressName !== '') {
3649
3649
  return Promise.resolve({
3650
3650
  status: '0',
3651
3651
  data: {
3652
3652
  areaId,
3653
3653
  fullAddress: addressName,
3654
3654
  },
3655
3655
  });
3656
3656
  } else {
3657
3657
  return Promise.resolve({
3658
3658
  status: '-1002',
3659
3659
  msg: '京购内嵌h5h5暂无业务需要,未实现,获取失败',
3660
3660
  });
3661
3661
  }
3662
3662
  } else {
3663
3663
  return Promise.resolve({
3664
3664
  status: '-1002',
3665
3665
  msg: '普通h5暂无业务需要,未实现,获取失败',
3666
3666
  });
3667
3667
  }
3668
3668
  }
3669
3669
 
3670
3670
  getJingGouMiniInh5Address() {
3671
3671
  let getRes: any = {
3672
3672
  areaId: '',
3673
3673
  addressName: '',
3674
3674
  };
3675
3675
  try {
3676
3676
  const getUrlHast = decodeURIComponent(window.location.hash || '');
3677
3677
  const sensMatch = getUrlHast ? getUrlHast.match(/sens=({.*?})/) : null;
3678
3678
  if (sensMatch && sensMatch[1]) {
3679
3679
  const sensData = JSON.parse(sensMatch[1]);
3680
3680
  const getWqAddr = sensData?.wq_addr || '';
3681
3681
  if (getWqAddr && /\|/.test(getWqAddr)) {
3682
3682
  const addressList = getWqAddr.split(/\|/);
3683
3683
  const [addressId, areaId, areaName, addressName, coordinate] = addressList;
3684
3684
  getRes = {
3685
3685
  addressId,
3686
3686
  areaId,
3687
3687
  areaName,
3688
3688
  addressName,
3689
3689
  coordinate,
3690
3690
  };
3691
3691
  }
3692
3692
  }
3693
3693
  } catch (e) {
3694
3694
  console.log('获取hash转换异常', e);
3695
3695
  }
3696
3696
  return getRes;
3697
3697
  }
3698
3698
 
3699
3699
  getAddressCachePromise() {
3700
3700
  return new Promise((resolve) => {
3701
3701
  if (this?.info?.sysInfo?.lat && this?.info?.sysInfo?.lng && this?.info?.sysInfo?.area) {
3702
3702
  resolve({
3703
3703
  lat: this.info.sysInfo.lat,
3704
3704
  lng: this.info.sysInfo.lng,
3705
3705
  area: this?.info?.sysInfo?.area,
3706
3706
  fullAddress: this?.info?.pageInfo?.fullAddress,
3707
3707
  });
3708
3708
  } else {
3709
3709
  this.getCacheAddressRouter()
3710
3710
  .then((res) => {
3711
3711
  const { status, data } = res;
3712
3712
  console.log('原生端获取经纬度及四级地址原始数据结果', status, data, res);
3713
3713
  if (status === '0' && data) {
3714
3714
  const {
3715
3715
  lat,
3716
3716
  latitude,
3717
3717
  lng,
3718
3718
  longitude,
3719
3719
  provinceId,
3720
3720
  cityId,
3721
3721
  countyId,
3722
3722
  townId,
3723
3723
  fullAddress,
3724
3724
  areaId,
3725
3725
  } = data || {};
3726
3726
  const getAreaIdsEnable = areaId && areaId !== '';
3727
3727
  const getEncodeFullAddress = fullAddress ? encodeURIComponent(fullAddress) : '';
3728
3728
  let area = getAreaIdsEnable ? areaId : '';
3729
3729
  this.info.sysInfo['lat'] = `${lat || latitude || ''}`;
3730
3730
  this.info.sysInfo['lng'] = `${lng || longitude || ''}`;
3731
3731
  const getProvinceIdNum = provinceId ? Number(provinceId) : 0;
3732
3732
  if ((getProvinceIdNum && getProvinceIdNum > 0) || getAreaIdsEnable) {
3733
3733
  area = getAreaIdsEnable
3734
3734
  ? areaId
3735
3735
  : `${provinceId}_${cityId || 0}_${countyId || 0}_${townId || 0}`;
3736
3736
  this.info.pageInfo['address'] = area;
3737
3737
  this.info.pageInfo['addressCommaStr'] = area.replace(/_/g, ',');
3738
3738
  this.info.sysInfo['area'] = area;
3739
3739
  const getUpdateData = {
3740
3740
  area: this.info.pageInfo.address,
3741
3741
  };
3742
3742
  if (fullAddress && fullAddress.length > 0) {
3743
3743
  getUpdateData['fullAddress'] = getEncodeFullAddress;
3744
3744
  this.info.pageInfo['fullAddress'] = getEncodeFullAddress;
3745
3745
  }
3746
3746
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, getUpdateData);
3747
3747
  }
3748
3748
  resolve({
3749
3749
  lat: this.info.sysInfo['lat'],
3750
3750
  lng: this.info.sysInfo['lng'],
3751
3751
  fullAddress: getEncodeFullAddress,
3752
3752
  area: area,
3753
3753
  });
3754
3754
  } else {
3755
3755
  if (typeof res === 'object') {
3756
3756
  draBusinessCustomReport({
3757
3757
  eventName: 'business',
3758
3758
  errorName: 'jdapp_getCacheAddress_info_err',
3759
3759
  errorMessage: '松果app内通过router协议获取用户地址及经纬度信息异常',
3760
3760
  extraData: JSON.stringify({
3761
3761
  isJdApp,
3762
3762
  jdAppVersion: jdAppVersionStr,
3763
3763
  ...res,
3764
3764
  }),
3765
3765
  });
3766
3766
  }
3767
3767
  resolve({ lat: '', lng: '', area: '', fullAddress: '' });
3768
3768
  }
3769
3769
  })
3770
3770
  .catch((e) => {
3771
3771
  console.log('getCacheAddressRouter catch e,获取经纬度信息异常e', e);
3772
3772
  draBusinessCustomReport({
3773
3773
  eventName: 'business',
3774
3774
  errorName: 'jdapp_getCacheAddress_info_catch_err',
3775
3775
  errorMessage: '松果app内通过router协议获取用户地址及经纬度信息catch异常',
3776
3776
  extraData: JSON.stringify({
3777
3777
  isJdApp,
3778
3778
  jdAppVersion: jdAppVersionStr,
3779
3779
  }),
3780
3780
  });
3781
3781
  resolve({ lat: '', lng: '', area: '', fullAddress: '' });
3782
3782
  });
3783
3783
  }
3784
3784
  });
3785
3785
  }
3786
3786
 
3787
3787
  getLbsCacheAddressRouter() {
3788
3788
  if (isJdApp) {
3789
3789
  if (!isJdAndHarmonyDevice) {
3790
3790
  return Promise.race([
3791
3791
  new Promise((resolve) => {
3792
3792
  const getCallBackName = `getJdLbsCacheAddress${Date.now()}`;
3793
3793
  if (!window[getCallBackName]) {
3794
3794
  window[getCallBackName] = (res) => {
3795
3795
  console.warn(`获取松果appGetJdLbsCacheAddressRes,返回结果`, res);
3796
3796
  try {
3797
3797
  const getResJson = typeof res === 'string' ? JSON.parse(res) : res;
3798
3798
  resolve(getResJson);
3799
3799
  } catch (e) {
3800
3800
  resolve({
3801
3801
  status: '-1002',
3802
3802
  msg: '地址信息解析json异常',
3803
3803
  res,
3804
3804
  });
3805
3805
  }
3806
3806
  window[getCallBackName] = null;
3807
3807
  };
3808
3808
  }
3809
3809
  const getRouterParam = {
3810
3810
  appid: '219f70bbbf7e4ede7968bedaa1beafb4',
3811
3811
  sceneId: 'basicShoppingProcess',
3812
3812
  };
3813
3813
  if (isAndroidDevice) {
3814
3814
  return callRouterAndroid({
3815
3815
  routerURL: 'router://com.jingdong.app.mall.location.JSLocationManager/getLocation',
3816
3816
  routerParam: getRouterParam,
3817
3817
  callBackName: getCallBackName,
3818
3818
  isSync: true,
3819
3819
  hasJdRouter: false,
3820
3820
  });
3821
3821
  } else {
3822
3822
  return callRouterIOS({
3823
3823
  routerURL: 'router://JDBLBSKitModule/getCacheAddressInfo',
3824
3824
  routerParam: getRouterParam,
3825
3825
  callBackName: getCallBackName,
3826
3826
  isSync: true,
3827
3827
  });
3828
3828
  }
3829
3829
  }),
3830
3830
  this.taskTimeoutPromise(() => {
3831
3831
  return {
3832
3832
  status: '-1000',
3833
3833
  msg: '原生router协议获取lbs地址信息3s超时',
3834
3834
  };
3835
3835
  }, 3000),
3836
3836
  ]);
3837
3837
  } else {
3838
3838
  return Promise.resolve({
3839
3839
  status: '-1001',
3840
3840
  msg: '鸿蒙系统调用未实现,获取失败',
3841
3841
  });
3842
3842
  }
3843
3843
  } else if (isH5AndJingGouMini) {
3844
3844
  return this.getLocationForGpsPromise();
3845
3845
  } else {
3846
3846
  return Promise.resolve({
3847
3847
  status: '-1002',
3848
3848
  msg: '普通h5暂无业务需要,未实现,获取失败',
3849
3849
  });
3850
3850
  }
3851
3851
  }
3852
3852
  getLocationForGpsPromise() {
3853
3853
  return new Promise((resolve) => {
3854
3854
  let hasGetLocationForGps = true;
3855
3855
  if (urlCookie && urlCookie['loc']) {
3856
3856
  const [provinceid = 0, cityid = 0, districtid = 0, townid = 0] =
3857
3857
  urlCookie['loc'].split('_');
3858
3858
  const getProvinceIdNum = provinceid ? Number(provinceid) : 0;
3859
3859
  if (getProvinceIdNum && getProvinceIdNum > 0) {
3860
3860
  hasGetLocationForGps = false;
3861
3861
  resolve({
3862
3862
  status: '0',
3863
3863
  data: {
3864
3864
  provinceid,
3865
3865
  cityid,
3866
3866
  districtid,
3867
3867
  townid,
3868
3868
  origin: 'wxapp',
3869
3869
  },
3870
3870
  });
3871
3871
  }
3872
3872
  }
3873
3873
  if (hasGetLocationForGps && window?.navigator?.geolocation) {
3874
3874
  window.navigator.geolocation.getCurrentPosition(
3875
3875
  (position) => {
3876
3876
  console.log('h5 浏览器通过原生geolocation获取经纬度结果', position?.coords);
3877
3877
  if (position?.coords) {
3878
3878
  resolve({
3879
3879
  status: '0',
3880
3880
  data: {
3881
3881
  srclat: position.coords?.latitude,
3882
3882
  srclng: position.coords.longitude,
3883
3883
  origin: 'h5',
3884
3884
  },
3885
3885
  });
3886
3886
  } else {
3887
3887
  resolve({
3888
3888
  status: '-1001',
3889
3889
  msg: 'h5 浏览器通过原生geolocation获取经纬度结果异常,详情见position',
3890
3890
  position,
3891
3891
  });
3892
3892
  }
3893
3893
  },
3894
3894
  (error) => {
3895
3895
  resolve({
3896
3896
  status: '-1001',
3897
3897
  msg: 'h5 浏览器通过原生geolocation获取经纬度结果定位异常,详情见error',
3898
3898
  error,
3899
3899
  });
3900
3900
  },
3901
3901
  {
3902
3902
  enableHighAccuracy: false,
3903
3903
  timeout: 3 * 1000,
3904
3904
  maximumAge: 10 * 60 * 1000,
3905
3905
  },
3906
3906
  );
3907
3907
  } else {
3908
3908
  resolve({
3909
3909
  status: '-1001',
3910
3910
  msg: '您的浏览器不支持地理定位',
3911
3911
  });
3912
3912
  }
3913
3913
  });
3914
3914
  }
3915
3915
 
3916
3916
  createLbsCacheAddress(realTimeArea) {
3917
3917
  const getLbsAddressCacheMinuteTime = Number(
3918
3918
  window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime || 0,
3919
3919
  );
3920
3920
  console.log(
3921
3921
  '获取lbs缓存到cookie的时间,分钟',
3922
3922
  getLbsAddressCacheMinuteTime,
3923
3923
  'lbsAddressCacheToCookieMinuteTime',
3924
3924
  window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime,
3925
3925
  );
3926
3926
  if (getLbsAddressCacheMinuteTime > 0) {
3927
3927
  const expires = new Date(Date.now() + getLbsAddressCacheMinuteTime * 60 * 1000);
3928
3928
  realTimeArea &&
3929
3929
  cookie.set(cacheH5LbsAddressKey, realTimeArea, {
3930
3930
  path: '/',
3931
3931
  expires,
3932
3932
  });
3933
3933
  }
3934
3934
  }
3935
3935
 
3936
3936
  getLbsAddressCachePromise() {
3937
3937
  if (!this.lbsAddressCachePromise) {
3938
3938
  this.lbsAddressCachePromise = new Promise((resolve) => {
3939
3939
  const getCookieForLbsAddress = window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime
3940
3940
  ? cookie.get(cacheH5LbsAddressKey)
3941
3941
  : '';
3942
3942
  const getUserLbsAddress = this?.info?.pageInfo?.userLbsAddress;
3943
3943
  if (getUserLbsAddress && getUserLbsAddress !== '') {
3944
3944
  resolve({
3945
3945
  ok: true,
3946
3946
  realTimeArea: getUserLbsAddress,
3947
3947
  });
3948
3948
  } else if (getCookieForLbsAddress && getCookieForLbsAddress !== '') {
3949
3949
  console.info(
3950
3950
  `通过cookie获取缓存的userLbsAddress,${window?.shopGlobalSwitch?.lbsAddressCacheToCookieMinuteTime}分钟内有效`,
3951
3951
  getCookieForLbsAddress,
3952
3952
  );
3953
3953
  this.info.pageInfo['userLbsAddress'] = getCookieForLbsAddress;
3954
3954
  this.info.sysInfo['realTimeArea'] = getCookieForLbsAddress;
3955
3955
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, {
3956
3956
  realTimeArea: getCookieForLbsAddress,
3957
3957
  });
3958
3958
  resolve({
3959
3959
  ok: true,
3960
3960
  realTimeArea: getCookieForLbsAddress,
3961
3961
  });
3962
3962
  } else {
3963
3963
  this.getLbsCacheAddressRouter()
3964
3964
  .then((res) => {
3965
3965
  const { status, data } = res;
3966
3966
  console.log(
3967
3967
  '原生或者内嵌京购端获取基于lbs的经纬度及四级地址原始数据结果',
3968
3968
  status,
3969
3969
  data,
3970
3970
  res,
3971
3971
  );
3972
3972
  if (status === '0' && data) {
3973
3973
  const { srclat, srclng, provinceid, cityid, districtid, townid, origin } =
3974
3974
  data || {};
3975
3975
  let realTimeArea = '';
3976
3976
  this.info.sysInfo['srclat'] = `${srclat || ''}`;
3977
3977
  this.info.sysInfo['srclng'] = `${srclng || ''}`;
3978
3978
  const getProvinceIdNum = provinceid ? Number(provinceid) : 0;
3979
3979
  if (getProvinceIdNum && getProvinceIdNum > 0) {
3980
3980
  realTimeArea = `${provinceid}_${cityid || 0}_${districtid || 0}_${townid || 0}`;
3981
3981
  this.info.pageInfo['userLbsAddress'] = realTimeArea;
3982
3982
  this.info.sysInfo['realTimeArea'] = realTimeArea;
3983
3983
  Taro.eventCenter.trigger(TaroEventType.USER_AREA_UPDATE, {
3984
3984
  realTimeArea: this.info.pageInfo.userLbsAddress,
3985
3985
  });
3986
3986
  this.createLbsCacheAddress(realTimeArea);
3987
3987
  } else {
3988
3988
  !origin && (this.lbsAddressCachePromise = null);
3989
3989
  }
3990
3990
  const getValidRealTimeArea = realTimeArea !== '';
3991
3991
  resolve({
3992
3992
  lat: this.info.sysInfo['srclat'],
3993
3993
  lng: this.info.sysInfo['srclng'],
3994
3994
  realTimeArea: realTimeArea,
3995
3995
  ok: getValidRealTimeArea,
3996
3996
  msg: getValidRealTimeArea
3997
3997
  ? '成功'
3998
3998
  : origin
3999
3999
  ? origin
4000
4000
  : '根据router底层获取lbs地址信息异常,详情见data',
4001
4001
  data: getValidRealTimeArea ? null : res,
4002
4002
  });
4003
4003
  if (!getValidRealTimeArea && !origin) {
4004
4004
  draBusinessCustomReport({
4005
4005
  eventName: 'business',
4006
4006
  errorName: 'h5_getLbsCacheAddress_info_err',
4007
4007
  errorMessage:
4008
4008
  '松果app内通过router协议获取基于lbs实时用户地址及经纬度信息catch异常',
4009
4009
  extraData: JSON.stringify({
4010
4010
  isJdApp,
4011
4011
  jdAppVersion: jdAppVersionStr,
4012
4012
  }),
4013
4013
  });
4014
4014
  }
4015
4015
  } else {
4016
4016
  typeof res === 'object' &&
4017
4017
  draBusinessCustomReport({
4018
4018
  eventName: 'business',
4019
4019
  errorName: 'h5_getLbsCacheAddress_info_err',
4020
4020
  errorMessage:
4021
4021
  'h5通过router协议或者浏览器gps获取基于lbs实时用户缓存地址及经纬度信息异常',
4022
4022
  extraData: JSON.stringify({
4023
4023
  isJdApp,
4024
4024
  jdAppVersion: jdAppVersionStr,
4025
4025
  ...res,
4026
4026
  }),
4027
4027
  });
4028
4028
  this.lbsAddressCachePromise = null;
4029
4029
  resolve({ realTimeArea: '', ok: false });
4030
4030
  }
4031
4031
  })
4032
4032
  .catch((e) => {
4033
4033
  console.log('getLbsAddressCachePromise catch e,获取经纬度信息异常e', e);
4034
4034
  this.lbsAddressCachePromise = null;
4035
4035
  draBusinessCustomReport({
4036
4036
  eventName: 'business',
4037
4037
  errorName: 'h5_getLbsCacheAddress_info_err',
4038
4038
  errorMessage:
4039
4039
  'h5内通过router协议获取浏览器gps获取基于lbs实时用户地址及经纬度信息catch异常',
4040
4040
  extraData: JSON.stringify({
4041
4041
  isJdApp,
4042
4042
  jdAppVersion: jdAppVersionStr,
4043
4043
  }),
4044
4044
  });
4045
4045
  resolve({ realTimeArea: '', ok: false });
4046
4046
  });
4047
4047
  }
4048
4048
  });
4049
4049
  }
4050
4050
  return this.lbsAddressCachePromise;
4051
4051
  }
4052
4052
 
4053
4053
  async updateMPaasConfigAsync(isBeforePageReady: boolean) {
4054
4054
  console.log('updateMPaasConfigAsync isBeforePageReady:', isBeforePageReady);
4055
4055
  if (!isJdApp) {
4056
4056
  return;
4057
4057
  }
4058
4058
  const avifSwitch = await getMPaasConfigByBussinessKey('avifSwitch', isBeforePageReady);
4059
4059
  this.info.sysInfo.dynamicConfig['avifSwitch'] = avifSwitch;
4060
4060
  const hybridHttpSwitch = await getMPaasConfigByBussinessKey(
4061
4061
  'hybridHttpSwitch',
4062
4062
  isBeforePageReady,
4063
4063
  );
4064
4064
  const jshopIsVipShopSwitch = await getMPaasConfigByBussinessKey(
4065
4065
  'jshopIsVipShop',
4066
4066
  isBeforePageReady,
4067
4067
  );
4068
4068
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = hybridHttpSwitch;
4069
4069
  this.info.sysInfo.dynamicConfig['jshopIsVipShopSwitch'] = jshopIsVipShopSwitch;
4070
4070
  const isFollowAppVideoPlayStatus = await getMPaasConfigByBussinessKey(
4071
4071
  'isFollowAppVideoPlayStatus',
4072
4072
  isBeforePageReady,
4073
4073
  );
4074
4074
  console.log(
4075
4075
  'isBeforePageReady:',
4076
4076
  isBeforePageReady,
4077
4077
  'isFollowAppVideoPlayStatus:',
4078
4078
  isFollowAppVideoPlayStatus,
4079
4079
  );
4080
4080
  if (isFollowAppVideoPlayStatus === true || isFollowAppVideoPlayStatus === 'true') {
4081
4081
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = true;
4082
4082
  }
4083
4083
  }
4084
4084
 
4085
4085
  async getWifiVideoAutoPlayAsync() {
4086
4086
  this.info.sysInfo['wifiVideoAutoPlay'] = false;
4087
4087
  if (!isJdApp) {
4088
4088
  return;
4089
4089
  }
4090
4090
  const videoPlayStatus = await getWifiVideoAutoPlay().catch((e) => {
4091
4091
  return 0;
4092
4092
  });
4093
4093
  if (Number(videoPlayStatus) === 1) {
4094
4094
  this.info.sysInfo['wifiVideoAutoPlay'] = true;
4095
4095
  }
4096
4096
  }
4097
4097
 
4098
4098
  async getMPaasConfigAsync() {
4099
4099
  this.info.sysInfo.dynamicConfig = {};
4100
4100
  this.info.sysInfo.dynamicConfig['avifSwitch'] = {};
4101
4101
  this.info.sysInfo.dynamicConfig['hybridHttpSwitch'] = {};
4102
4102
  this.info.sysInfo.dynamicConfig['jshopIsVipShopSwitch'] = {};
4103
4103
  this.info.sysInfo.dynamicConfig['isFollowAppVideoPlayStatus'] = false;
4104
4104
  return this.updateMPaasConfigAsync(true);
4105
4105
  }
4106
4106
 
4107
4107
  getDynamicConfig(key: string) {
4108
4108
  return this.info.sysInfo?.dynamicConfig?.[key];
4109
4109
  }
4110
4110
  async updateMPaasConfig() {
4111
4111
  console.log('updateMPaasConfig');
4112
4112
  if (
4113
4113
  isIosDevice &&
4114
4114
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_VERSION) < 0 &&
4115
4115
  versionCompare(jdAppVersionStr, MPAAS_CONFIG_APP_LOW_VERSION) >= 0
4116
4116
  ) {
4117
4117
  try {
4118
4118
  await this.updateMPaasConfigAsync(false);
4119
4119
  } catch (e) {
4120
4120
  console.log('updateMPaasConfigAsync:', e);
4121
4121
  }
4122
4122
  }
4123
4123
  }
4124
4124
 
4125
4125
  toLogin(options) {
4126
4126
  if (isAscfApp) {
4127
4127
  return this.toAscfAppLogin(options);
4128
4128
  }
4129
4129
  return this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState
4130
4130
  ? this.toWxAppLogin(options)
4131
4131
  : this.toWebLogin(options);
4132
4132
  }
4133
4133
 
4134
4134
  doLogin(options) {
4135
4135
  return this.toLogin(options);
4136
4136
  }
4137
4137
 
4138
4138
  doLoginForJdPin(options = {}) {
4139
4139
  return this.doLogin({
4140
4140
  loginColor: {
4141
4141
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
4142
4142
  dpin: 0,
4143
4143
  },
4144
4144
  ...options,
4145
4145
  });
4146
4146
  }
4147
4147
 
4148
4148
  toWebLogin(options) {
4149
4149
  let params: {
4150
4150
  returnurl: string;
4151
4151
  } = {
4152
4152
  returnurl: '',
4153
4153
  };
4154
4154
  const checkToPcLogin = options ? options?.isPc : isPc;
4155
4155
  const loginUrl = checkToPcLogin
4156
4156
  ? `//passport.jd.com/new/login.aspx`
4157
4157
  : `${domain.mobileLogin}/user/login.action`;
4158
4158
  const defaultParams = {
4159
4159
  appid: /\.jd\.hk/.test(window.location.hostname) ? '233' : '100',
4160
4160
  returnurl: window.location.href,
4161
4161
  };
4162
4162
  if (isString(options)) {
4163
4163
  params = Object.assign({}, defaultParams, {
4164
4164
  returnurl: options,
4165
4165
  });
4166
4166
  } else if (isObject(options)) {
4167
4167
  const { loginColor, ...otherOptions } = options;
4168
4168
  params = Object.assign({}, defaultParams, otherOptions);
4169
4169
  } else {
4170
4170
  params = defaultParams;
4171
4171
  }
4172
4172
  params.returnurl = encodeURIComponent(params.returnurl);
4173
4173
  let getFullUrl = loginUrl + '?' + serialize(params);
4174
4174
  if (checkToPcLogin) {
4175
4175
  getFullUrl = getFullUrl.replace(/returnurl/, 'ReturnUrl');
4176
4176
  }
4177
4177
  return Promise.resolve({
4178
4178
  h5ToUrl: true,
4179
4179
  url: getFullUrl,
4180
4180
  }).then(() => {
4181
4181
  window.location.href = getFullUrl;
4182
4182
  });
4183
4183
  }
4184
4184
 
4185
4185
  toAscfAppLogin(options = {}) {
4186
4186
  console.log('华为元服务中h5登录跳转', options);
4187
4187
  return Promise.resolve(true).then(() => {
4188
4188
  const returnPage = encodeURIComponent(window.location.href);
4189
4189
  if (has && has.ascfweb) {
4190
4190
  has.ascfweb.redirectTo({
4191
4191
  url: `/pages/login/index/index?isH5=1&returnPage=${returnPage}&pageType=h5&source=shopx`,
4192
4192
  });
4193
4193
  }
4194
4194
  });
4195
4195
  }
4196
4196
 
4197
4197
  toWxAppLogin(options = {}) {
4198
4198
  console.log('微信京购小程序中h5登录跳转', options);
4199
4199
  return Promise.resolve(true).then(() => {
4200
4200
  const { loginColor } = Object.assign(
4201
4201
  {},
4202
4202
  {
4203
4203
  loginColor: {
4204
4204
  biz: WXAPP_BIZ_KEY,
4205
4205
  dpin: 1,
4206
4206
  },
4207
4207
  },
4208
4208
  options,
4209
4209
  );
4210
4210
  window.location.href = `${domain.wq}/pinbind/pintokenredirect?biz=${
4211
4211
  loginColor.biz
4212
4212
  }&url=${encodeURIComponent(window.location.href)}`;
4213
4213
  });
4214
4214
  }
4215
4215
 
4216
4216
  getLoginCookie() {
4217
4217
  return Promise.resolve({
4218
4218
  pin: cookie.get('pin') || '',
4219
4219
  });
4220
4220
  }
4221
4221
 
4222
4222
  clearLoginCookie() {
4223
4223
  cookie.remove('pin');
4224
4224
  }
4225
4225
 
4226
4226
  checkStatusAndLogin(options = {}) {
4227
4227
  if (!this.checkStatusAndLoginPromise) {
4228
4228
  this.checkStatusAndLoginPromise = new Promise(async (resolve, reject) => {
4229
4229
  try {
4230
4230
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
4231
4231
  if (getLoginState) {
4232
4232
  resolve(true);
4233
4233
  } else {
4234
4234
  this.toLogin(options);
4235
4235
  reject(false);
4236
4236
  }
4237
4237
  } catch (e) {
4238
4238
  this.toLogin(options);
4239
4239
  reject(false);
4240
4240
  }
4241
4241
  });
4242
4242
  return this.checkStatusAndLoginPromise;
4243
4243
  } else {
4244
4244
  return this.checkStatusAndLoginPromise
4245
4245
  .then(() => {
4246
4246
  return Promise.resolve(true);
4247
4247
  })
4248
4248
  .catch(() => {
4249
4249
  this.toLogin(options);
4250
4250
  return Promise.reject(true);
4251
4251
  });
4252
4252
  }
4253
4253
  }
4254
4254
 
4255
4255
  checkJdStatusAndLogin(
4256
4256
  options = {
4257
4257
  loginColor: {
4258
4258
  biz: WXAPP_BIZ_SHOP_LIGHT_KEY,
4259
4259
  dpin: 0,
4260
4260
  },
4261
4261
  },
4262
4262
  ) {
4263
4263
  return this.checkStatusAndLogin(options);
4264
4264
  }
4265
4265
 
4266
4266
  doCheckLoginStateAndForApiCheck(options) {
4267
4267
  if (this.info.loginState) {
4268
4268
  return Promise.resolve(true);
4269
4269
  } else {
4270
4270
  return new Promise((resolve, reject) => {
4271
4271
  if (this.info.isJingGouMiniViewState || this.info.isJingxiMiniViewState) {
4272
4272
  const getWqAuthToken = cookie.get('wq_auth_token');
4273
4273
  const getWqSkey = cookie.get('wq_skey');
4274
4274
  const getWqUin = cookie.get('wq_uin');
4275
4275
  const isLoginState =
4276
4276
  options?.loginColor?.dpin === 0 ? getWqAuthToken : getWqSkey && getWqUin;
4277
4277
  if (isLoginState) {
4278
4278
  this.info.loginState = true;
4279
4279
  resolve(true);
4280
4280
  } else {
4281
4281
  reject(false);
4282
4282
  }
4283
4283
  } else {
4284
4284
  Taro.request({
4285
4285
  url: api.isLogin,
4286
4286
  jsonp: true,
4287
4287
  timeout: 3000,
4288
4288
  success: (res) => {
4289
4289
  const { statusCode, data } = res;
4290
4290
  if (statusCode === 200 && data?.islogin && Number(data.islogin) === 1) {
4291
4291
  this.info.loginState = true;
4292
4292
  resolve(true);
4293
4293
  } else {
4294
4294
  reject(false);
4295
4295
  }
4296
4296
  },
4297
4297
  fail: (err) => {
4298
4298
  console.log('登录检查异常', err);
4299
4299
  reject(false);
4300
4300
  },
4301
4301
  });
4302
4302
  }
4303
4303
  });
4304
4304
  }
4305
4305
  }
4306
4306
 
4307
4307
  checkLoginStatus(options) {
4308
4308
  return new Promise(async (resolve, reject) => {
4309
4309
  try {
4310
4310
  const getLoginState = await this.doCheckLoginStateAndForApiCheck(options);
4311
4311
  if (getLoginState) {
4312
4312
  const { pin } = await this.getLoginCookie();
4313
4313
  this.info.userInfo = {
4314
4314
  pin,
4315
4315
  encodePin: encodeURIComponent(pin),
4316
4316
  ptkey: '',
4317
4317
  };
4318
4318
  resolve(true);
4319
4319
  } else {
4320
4320
  reject(false);
4321
4321
  }
4322
4322
  } catch (e) {
4323
4323
  reject(false);
4324
4324
  }
4325
4325
  });
4326
4326
  }
4327
4327
 
4328
4328
  updatePageAndLogInfo(updateQuery = {}) {
4329
4329
  const createUpdateQueryInfo: {
4330
4330
  query: {
4331
4331
  shopId?: string | number;
4332
4332
  venderId?: string | number;
4333
4333
  };
4334
4334
  updateShopInfoState: boolean;
4335
4335
  } = Object.assign(
4336
4336
  {},
4337
4337
  {
4338
4338
  query: {},
4339
4339
  updateShopInfoState: false,
4340
4340
  },
4341
4341
  updateQuery,
4342
4342
  );
4343
4343
  console.log(
4344
4344
  '获取当前下发的店铺查询参数',
4345
4345
  updateQuery,
4346
4346
  '获取之前保存的shopInfo店铺查询参数',
4347
4347
  this.info?.shopInfo,
4348
4348
  );
4349
4349
  const { query, updateShopInfoState } = createUpdateQueryInfo;
4350
4350
  const { shopId, venderId, un_area } = query;
4351
4351
  if (updateShopInfoState) {
4352
4352
  this.info.queryInfo = {
4353
4353
  ...this.info.queryInfo,
4354
4354
  ...query,
4355
4355
  };
4356
4356
  if (shopId && venderId) {
4357
4357
  this.info.shopInfo = {
4358
4358
  shopId: `${shopId}`,
4359
4359
  venderId: `${venderId}`,
4360
4360
  };
4361
4361
  }
4362
4362
  } else {
4363
4363
  this.info.queryInfo = {
4364
4364
  ...query,
4365
4365
  };
4366
4366
  if (
4367
4367
  this.info.shopInfo?.shopId &&
4368
4368
  this.info.shopInfo?.venderId &&
4369
4369
  (this.info.shopInfo.shopId == shopId || this.info.shopInfo.venderId == venderId)
4370
4370
  ) {
4371
4371
  this.info.queryInfo.shopId = this.info.shopInfo.shopId;
4372
4372
  this.info.queryInfo.venderId = this.info.shopInfo.venderId;
4373
4373
  console.log(
4374
4374
  '当前存储的店铺shopId和venderId与下发的店铺信息shopId或者venderId为同一个,补充shopId或者venderId查询参数',
4375
4375
  this.info.queryInfo,
4376
4376
  );
4377
4377
  }
4378
4378
  }
4379
4379
  this.info.queryInfo['shopId'] &&
4380
4380
  (this.info.queryInfo['shopId'] = `${this.info.queryInfo['shopId']}`);
4381
4381
  this.info.queryInfo['venderId'] &&
4382
4382
  (this.info.queryInfo['venderId'] = `${this.info.queryInfo['venderId']}`);
4383
4383
  console.log(
4384
4384
  'h5==获取店铺下发查询参数\n',
4385
4385
  query,
4386
4386
  '\n获取店铺最后查询参数\n',
4387
4387
  this.info.queryInfo,
4388
4388
  '\n是否为更新店铺状态\n',
4389
4389
  updateShopInfoState,
4390
4390
  );
4391
4391
  const changeArea = un_area && un_area.length > 0 ? un_area : isPc && ipLoc_djd ? ipLoc_djd : '';
4392
4392
  if (changeArea) {
4393
4393
  const getBottomAreaStr = changeArea.replace(/-/g, '_');
4394
4394
  this.info.pageInfo.address = getBottomAreaStr;
4395
4395
  this.info.pageInfo.un_area = getBottomAreaStr;
4396
4396
  this.info.pageInfo.addressCommaStr = getBottomAreaStr.replace(/_/g, ',');
4397
4397
  }
4398
4398
  }
4399
4399
 
4400
4400
  dealLoadSdkList() {
4401
4401
  const globalLoadJsList = window?.shopGlobalSwitch?.asyncLoadJsList ?? [];
4402
4402
  const businessLoadJsList = window?.PAGE_DATA?.businessData?.asyncLoadJsList ?? [];
4403
4403
  const concatLoadJsList = [].concat(globalLoadJsList, businessLoadJsList);
4404
4404
  let mergeLoadJsList = globalLoadJsList;
4405
4405
  try {
4406
4406
  mergeLoadJsList = concatLoadJsList.reduce((accArr: any[], current: any) => {
4407
4407
  const getFindIndex = accArr.findIndex((item) => item?.fileName === current?.fileName);
4408
4408
  getFindIndex !== -1
4409
4409
  ? (accArr[getFindIndex] = { ...accArr[getFindIndex], ...current })
4410
4410
  : accArr.push(current);
4411
4411
  return accArr;
4412
4412
  }, []);
4413
4413
  } catch (e) {
4414
4414
  console.log('LoadJsList合并错误', e);
4415
4415
  }
4416
4416
  console.log(
4417
4417
  'globalLoadJsList',
4418
4418
  globalLoadJsList,
4419
4419
  'businessLoadJsList',
4420
4420
  businessLoadJsList,
4421
4421
  '两个加载jsList集合合并完成',
4422
4422
  mergeLoadJsList,
4423
4423
  );
4424
4424
  this.loadJsSdkList = mergeLoadJsList;
4425
4425
  return this.loadJsSdkList;
4426
4426
  }
4427
4427
 
4428
4428
  renderNextTickLoadSdk(delayTime = 1000, callback) {
4429
4429
  Taro.nextTick(() => {
4430
4430
  console.log(
4431
4431
  '页面渲染的下一帧执行的js加载方法,当前nextTick存在state的渲染问题,先延迟1s=======',
4432
4432
  );
4433
4433
  setTimeout(() => {
4434
4434
  this.loadOtherSdk(LoadJsInitTriggerType.NRXT_TICK, this.loadJsSdkList);
4435
4435
  typeof callback === 'function' && callback();
4436
4436
  }, delayTime);
4437
4437
  });
4438
4438
  }
4439
4439
 
4440
4440
  async loadOtherSdk(triggerType = LoadJsInitTriggerType.NOW, loadJsList: any[] = []) {
4441
4441
  const getLoadJsList =
4442
4442
  Array.isArray(loadJsList) && loadJsList.length > 0 ? loadJsList : this.dealLoadSdkList();
4443
4443
  const getLoadFilterList = getLoadJsList.filter((item) => {
4444
4444
  if (isJdAndHarmonyDevice && item.fileName === 'addCartJs') {
4445
4445
  item.initLoadType = undefined;
4446
4446
  }
4447
4447
  const getInitLoadEnvType = item?.initLoadEnvType || LoadJsInitLoadEnvType.ALL;
4448
4448
  let getLoastLoadEventState = true;
4449
4449
  if (getInitLoadEnvType === LoadJsInitLoadEnvType.JD_APP) {
4450
4450
  getLoastLoadEventState = isJdApp;
4451
4451
  }
4452
4452
  else if (getInitLoadEnvType === LoadJsInitLoadEnvType.M) {
4453
4453
  getLoastLoadEventState = !isJdApp || !!isJdAndHarmonyDevice;
4454
4454
  }
4455
4455
  const getInitTriggerType =
4456
4456
  isJdApp && item?.initJdAppTriggerType
4457
4457
  ? item?.initJdAppTriggerType
4458
4458
  : item?.initTriggerType || LoadJsInitTriggerType.NOW;
4459
4459
  const getInitLinkTriggerWay = window?.PAGE_DATA[item?.initLinkTriggerWay] || false;
4460
4460
  return getLoastLoadEventState && getInitTriggerType === triggerType && getInitLinkTriggerWay;
4461
4461
  });
4462
4462
  console.log(
4463
4463
  '获取当前触发方式',
4464
4464
  triggerType,
4465
4465
  '获取当前最后加载的js集合',
4466
4466
  getLoadFilterList,
4467
4467
  '过滤前的加载集合',
4468
4468
  getLoadJsList,
4469
4469
  );
4470
4470
  const loadTasks =
4471
4471
  getLoadFilterList.length > 0
4472
4472
  ? getLoadFilterList.map((item) => {
4473
4473
  const isLoadState = /sgm/.test(item?.fileName)
4474
4474
  ? window?.shopGlobalSwitch?.openSgm === 'true'
4475
4475
  : true;
4476
4476
  if (!isLoadState) {
4477
4477
  return Promise.resolve(true);
4478
4478
  }
4479
4479
  return this.loadItemSdkPromise(item)
4480
4480
  .then((res) => {
4481
4481
  console.info('当前js地址' + item?.src, '加载状态', res);
4482
4482
  const isFileNameNewDraSdkJs = res?.fileName === 'newDraSdkJs';
4483
4483
  if (isFileNameNewDraSdkJs && window?.dra?.run) {
4484
4484
  const getNewdraEnableShopIdPercentObj =
4485
4485
  window?.PAGE_DATA?.businessData?.newDraEnableShopIdPercent || null;
4486
4486
  const getNewdraEnableVenderIdPercentObj =
4487
4487
  window?.PAGE_DATA?.businessData?.newDraEnableVenderIdPercent || null;
4488
4488
  let canInitDraRun = true;
4489
4489
  if (getNewdraEnableShopIdPercentObj || getNewdraEnableVenderIdPercentObj) {
4490
4490
  canInitDraRun = this.shouldPercentExecuteNewDra(
4491
4491
  this.getNewDraEnablePercentNum(),
4492
4492
  );
4493
4493
  }
4494
4494
  if (canInitDraRun) {
4495
4495
  window.dra.run('init', { aid: res?.aid });
4496
4496
  window.dra.run('start');
4497
4497
  }
4498
4498
  }
4499
4499
  return true;
4500
4500
  })
4501
4501
  .catch((err) => {
4502
4502
  console.info('当前js地址加载异常', item?.src);
4503
4503
  window?.fetchErrorData &&
4504
4504
  window.fetchErrorData({
4505
4505
  title: '公共js加载异常',
4506
4506
  type: 'jsLoad',
4507
4507
  data: err,
4508
4508
  });
4509
4509
  return true;
4510
4510
  });
4511
4511
  })
4512
4512
  : [];
4513
4513
  return loadTasks.length ? Promise.allSettled(loadTasks) : Promise.resolve([]);
4514
4514
  }
4515
4515
 
4516
4516
  shouldPercentExecuteNewDra(percent) {
4517
4517
  if (percent <= 0) return false;
4518
4518
  if (percent >= 100) return true;
4519
4519
  const getRes = Math.random() < percent / 100;
4520
4520
  console.log('获取dra初始化执行的概率为', percent, '执行结果', getRes);
4521
4521
  return getRes;
4522
4522
  }
4523
4523
 
4524
4524
  getNewDraEnablePercentNum() {
4525
4525
  const getNewdraEnableShopIdPercent =
4526
4526
  window?.PAGE_DATA?.businessData?.newDraEnableShopIdPercent || {};
4527
4527
  const getNewdraEnableVenderIdPercent =
4528
4528
  window?.PAGE_DATA?.businessData?.newDraEnableVenderIdPercent || {};
4529
4529
  const getShopId = parseQueryUrlObj?.shopId || '';
4530
4530
  const getVenderId = parseQueryUrlObj?.venderId || '';
4531
4531
  const getShopIdDraEnablePercent = getNewdraEnableShopIdPercent[getShopId]
4532
4532
  ? getNewdraEnableShopIdPercent[getShopId]
4533
4533
  : getNewdraEnableShopIdPercent?.ids?.includes(getShopId)
4534
4534
  ? getNewdraEnableShopIdPercent?.idsNumber
4535
4535
  : -1;
4536
4536
  const getVenderIdDraEnablePercent = getNewdraEnableVenderIdPercent[getVenderId]
4537
4537
  ? getNewdraEnableVenderIdPercent[getVenderId]
4538
4538
  : getNewdraEnableVenderIdPercent?.ids?.includes(getVenderId)
4539
4539
  ? getNewdraEnableVenderIdPercent?.idsNumber
4540
4540
  : -1;
4541
4541
  if (getShopIdDraEnablePercent > -1 || getVenderIdDraEnablePercent > -1) {
4542
4542
  return getShopIdDraEnablePercent || getVenderIdDraEnablePercent;
4543
4543
  }
4544
4544
  return 100;
4545
4545
  }
4546
4546
  loadScriptEle(jsInfo, resolve, reject) {
4547
4547
  const getFileName = jsInfo?.fileName;
4548
4548
  if (getFileName) {
4549
4549
  const getEleId = `J_loadJs_${getFileName}`;
4550
4550
  const getEle = document.getElementById(getEleId);
4551
4551
  if (!getEle) {
4552
4552
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
4553
4553
  const _sgmEle = document.createElement('script');
4554
4554
  _sgmEle.id = getEleId;
4555
4555
  _sgmEle.onload = function () {
4556
4556
  resolve({
4557
4557
  ...jsInfo,
4558
4558
  jsTip: 'js加载成功',
4559
4559
  });
4560
4560
  };
4561
4561
  _sgmEle.onerror = function () {
4562
4562
  reject({
4563
4563
  ...jsInfo,
4564
4564
  env: getSgmCustomCode(jsLoadErrorSgmCode),
4565
4565
  jsReqError: '当前js创建标签触发onerror异常回调,请排查网络络错误或语法错误或运行时错误',
4566
4566
  });
4567
4567
  };
4568
4568
  const dataAttrList = ['timeout', 'fileName', 'env'];
4569
4569
  const getJsInfoKeyList = Object.keys(jsInfo);
4570
4570
  getJsInfoKeyList.forEach((key) => {
4571
4571
  if (key === 'async') {
4572
4572
  _sgmEle.async = jsInfo[key];
4573
4573
  } else if (key === 'crossOrigin') {
4574
4574
  _sgmEle.crossOrigin = jsInfo[key];
4575
4575
  } else if (key === 'src') {
4576
4576
  _sgmEle.src = `${jsInfo[key]}`;
4577
4577
  } else if (dataAttrList.includes(key) || /init/.test(key)) {
4578
4578
  _sgmEle.setAttribute(`data-${key}`, jsInfo[key]);
4579
4579
  } else {
4580
4580
  _sgmEle.setAttribute(key, jsInfo[key]);
4581
4581
  }
4582
4582
  });
4583
4583
  document.head.appendChild(_sgmEle);
4584
4584
  } else {
4585
4585
  console.log(`当前${jsInfo?.fileName || 'js'}已经存在页面中,可以直接调用相关方法`, jsInfo);
4586
4586
  resolve({
4587
4587
  ...jsInfo,
4588
4588
  jsTip: 'js本身已存在页面中',
4589
4589
  });
4590
4590
  }
4591
4591
  } else {
4592
4592
  console.warn('当前js资源信息缺少必要的参数fileName,请关注', jsInfo);
4593
4593
  }
4594
4594
  }
4595
4595
 
4596
4596
  loadItemSdkPromise(jsInfo: Record<string, any> = {}): Promise<any> {
4597
4597
  if (jsInfo?.src) {
4598
4598
  const getInitLoadType =
4599
4599
  isJdApp && jsInfo?.initJdAppLoadType
4600
4600
  ? jsInfo?.initJdAppLoadType
4601
4601
  : jsInfo?.initLoadType || LoadJsInitLoadType.ALL;
4602
4602
  if (getInitLoadType !== LoadJsInitLoadType.NONE) {
4603
4603
  const getFileKeyName = jsInfo?.fileName || jsInfo?.src;
4604
4604
  if (!this.loadJsSdkListCachePromise[getFileKeyName]) {
4605
4605
  if (getInitLoadType !== LoadJsInitLoadType.INSERT_ELE) {
4606
4606
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
4607
4607
  const jsLoadErrorSgmCode = `jsLoadError_${jsInfo?.fileName || 'customJs'}`;
4608
4608
  try {
4609
4609
  const jsXhrRequest = new XMLHttpRequest();
4610
4610
  jsXhrRequest.timeout = jsInfo?.timeout ?? 2000;
4611
4611
  const jsUrl = `${jsInfo?.src}`;
4612
4612
  jsXhrRequest.open('GET', jsUrl, true);
4613
4613
  jsXhrRequest.onreadystatechange = () => {
4614
4614
  if (jsXhrRequest.readyState === 4) {
4615
4615
  const getReqStatus = jsXhrRequest.status;
4616
4616
  const statusText = jsXhrRequest.statusText;
4617
4617
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
4618
4618
  const getInsetHeadState = getInitLoadType === LoadJsInitLoadType.ALL;
4619
4619
  if (getInsetHeadState) {
4620
4620
  this.loadScriptEle(jsInfo, resolve, reject);
4621
4621
  } else {
4622
4622
  resolve({
4623
4623
  ...jsInfo,
4624
4624
  jsTip: 'js请求成功,暂未插入head节点,业务自行单独插入',
4625
4625
  });
4626
4626
  }
4627
4627
  getReqStatus !== 200 &&
4628
4628
  draBusinessCustomReport({
4629
4629
  eventName: 'business',
4630
4630
  errorName: 'js_load_special_code',
4631
4631
  errorMessage: '当前js加载成功,状态非200,特殊上报观察',
4632
4632
  extraData: JSON.stringify({
4633
4633
  msg: '当前js加载成功,状态非200,特殊上报观察',
4634
4634
  jsReqState: getReqStatus,
4635
4635
  env: getSgmCustomCode('js_load_special_code'),
4636
4636
  data: jsInfo,
4637
4637
  }),
4638
4638
  });
4639
4639
  } else {
4640
4640
  const getRes = {
4641
4641
  ...jsInfo,
4642
4642
  env: getSgmCustomCode(jsLoadErrorSgmCode),
4643
4643
  jsReqError: `请求状态异常,状态码为${getReqStatus},statusText:${statusText}`,
4644
4644
  jsReqState: getReqStatus,
4645
4645
  };
4646
4646
  console.log('当前js请求状态异常,具体信息见', getRes);
4647
4647
  reject(getRes);
4648
4648
  }
4649
4649
  }
4650
4650
  };
4651
4651
  jsXhrRequest.onerror = () => {
4652
4652
  const getRes = {
4653
4653
  ...jsInfo,
4654
4654
  env: getSgmCustomCode(jsLoadErrorSgmCode),
4655
4655
  jsReqError: '请求错误',
4656
4656
  };
4657
4657
  console.log('当前js请求错误', getRes);
4658
4658
  jsXhrRequest.abort();
4659
4659
  reject(getRes);
4660
4660
  };
4661
4661
  jsXhrRequest.ontimeout = () => {
4662
4662
  const getRes = {
4663
4663
  ...jsInfo,
4664
4664
  env: getSgmCustomCode(jsLoadErrorSgmCode),
4665
4665
  jsReqError: `请求${jsXhrRequest.timeout}ms超时异常`,
4666
4666
  jsReqState: jsXhrRequest.status,
4667
4667
  };
4668
4668
  console.log('当前js请求超时异常', getRes);
4669
4669
  jsXhrRequest.abort();
4670
4670
  reject(getRes);
4671
4671
  };
4672
4672
  jsXhrRequest.send();
4673
4673
  } catch (e) {
4674
4674
  console.log('执行js请求异常', e);
4675
4675
  reject({
4676
4676
  ...jsInfo,
4677
4677
  env: getSgmCustomCode(jsLoadErrorSgmCode),
4678
4678
  jsReqError: '未知异常',
4679
4679
  error: e,
4680
4680
  });
4681
4681
  }
4682
4682
  });
4683
4683
  } else {
4684
4684
  this.loadJsSdkListCachePromise[getFileKeyName] = new Promise((resolve, reject) => {
4685
4685
  return this.loadScriptEle(jsInfo, resolve, reject);
4686
4686
  });
4687
4687
  }
4688
4688
  }
4689
4689
  return this.loadJsSdkListCachePromise[getFileKeyName];
4690
4690
  } else {
4691
4691
  return Promise.resolve({
4692
4692
  ...jsInfo,
4693
4693
  jsTip: 'js加载方式设置为不加载,当前不做处理',
4694
4694
  });
4695
4695
  }
4696
4696
  } else {
4697
4697
  return Promise.reject(jsInfo);
4698
4698
  }
4699
4699
  }
4700
4700
 
4701
4701
  createLanguagePromise() {
4702
4702
  const getLanguageConfig = window?.shopGlobalSwitch?.language || {};
4703
4703
  if (!this.languageCacheProimse) {
4704
4704
  this.languageCacheProimse = new Promise((resolve, reject) => {
4705
4705
  const { fileName, prefixUrl } = getLanguageConfig;
4706
4706
  console.log('getLanguageConfig', getLanguageConfig, 'languageNowType', languageNowType);
4707
4707
  const dealLanguageFile = () => {
4708
4708
  this.getLanguageFilePromise(getLanguageConfig, languageNowType)
4709
4709
  .then((res: any) => {
4710
4710
  if (res && res?.data) {
4711
4711
  this.languageJsonData = res.data;
4712
4712
 
4713
4713
  setTimeout(() => {
4714
4714
  const getOtherLanguageList = languageTypeList.filter(
4715
4715
  (item) => item !== languageNowType,
4716
4716
  );
4717
4717
  getOtherLanguageList.length > 0 &&
4718
4718
  getOtherLanguageList.map((languageTypeKey) => {
4719
4719
  this.getLanguageFilePromise(getLanguageConfig, languageTypeKey);
4720
4720
  });
4721
4721
  }, 3000);
4722
4722
  resolve(res);
4723
4723
  } else {
4724
4724
  reject(res);
4725
4725
  }
4726
4726
  })
4727
4727
  .catch((err) => {
4728
4728
  reject(err);
4729
4729
  });
4730
4730
  };
4731
4731
  if (fileName && prefixUrl) {
4732
4732
  const getLangStorageKey = `jshopx_lang_${languageNowType}`;
4733
4733
  const getLocalLangRes = getTaroStorageKeyValue(getLangStorageKey);
4734
4734
  if (getLocalLangRes) {
4735
4735
  try {
4736
4736
  const getLocalLangJsonData =
4737
4737
  typeof getLocalLangRes === 'string' ? JSON.parse(getLocalLangRes) : getLocalLangRes;
4738
4738
  if (getLocalLangJsonData?.fileName && getLocalLangJsonData?.data) {
4739
4739
  if (getLocalLangJsonData?.fileName === fileName) {
4740
4740
  const geThisLangData = getLocalLangJsonData.data;
4741
4741
  this.languageJsonData = geThisLangData;
4742
4742
  return resolve({
4743
4743
  ...getLanguageConfig,
4744
4744
  languageNowType,
4745
4745
  data: geThisLangData,
4746
4746
  });
4747
4747
  } else {
4748
4748
  dealLanguageFile();
4749
4749
  }
4750
4750
  } else {
4751
4751
  dealLanguageFile();
4752
4752
  }
4753
4753
  } catch (e) {
4754
4754
  return reject({
4755
4755
  languageNowType,
4756
4756
  msg: '转换错误',
4757
4757
  ...getLanguageConfig,
4758
4758
  });
4759
4759
  }
4760
4760
  } else {
4761
4761
  dealLanguageFile();
4762
4762
  }
4763
4763
  } else {
4764
4764
  return reject({
4765
4765
  languageNowType,
4766
4766
  msg: '文件对象下发异常',
4767
4767
  ...getLanguageConfig,
4768
4768
  });
4769
4769
  }
4770
4770
  });
4771
4771
  }
4772
4772
  return this.languageCacheProimse;
4773
4773
  }
4774
4774
 
4775
4775
  getLanguageFilePromise(info, languageTypeKey) {
4776
4776
  const { fileName, prefixUrl, timeout } = info || {};
4777
4777
  const getUrl = `${prefixUrl}${fileName}_${languageTypeKey}.json`;
4778
4778
  return new Promise((resolve, reject) => {
4779
4779
  const langLoadErrorSgmCode = `languageLoadError_${fileName || 'lang.json'}`;
4780
4780
  try {
4781
4781
  const langXhrRequest = new XMLHttpRequest();
4782
4782
  langXhrRequest.timeout = timeout || 2000;
4783
4783
  langXhrRequest.open('GET', getUrl, true);
4784
4784
  langXhrRequest.responseType = 'json';
4785
4785
  langXhrRequest.onreadystatechange = () => {
4786
4786
  if (langXhrRequest.readyState === 4) {
4787
4787
  const getReqStatus = langXhrRequest.status;
4788
4788
  const statusText = langXhrRequest.statusText;
4789
4789
  if ((getReqStatus >= 200 && getReqStatus < 300) || getReqStatus === 304) {
4790
4790
  const getData = langXhrRequest?.response || false;
4791
4791
  if (getData) {
4792
4792
  setTaroStorage(`jshopx_lang_${languageTypeKey}`, {
4793
4793
  fileName,
4794
4794
  data: getData,
4795
4795
  });
4796
4796
  resolve({
4797
4797
  ...info,
4798
4798
  languageTypeKey,
4799
4799
  data: getData,
4800
4800
  });
4801
4801
  } else {
4802
4802
  reject({
4803
4803
  ...info,
4804
4804
  languageTypeKey,
4805
4805
  msg: '数据获取异常',
4806
4806
  });
4807
4807
  }
4808
4808
  } else {
4809
4809
  const getRes = {
4810
4810
  ...info,
4811
4811
  languageTypeKey,
4812
4812
  env: getSgmCustomCode(langLoadErrorSgmCode),
4813
4813
  msg: `请求状态异常,状态码为${getReqStatus},statusText:${statusText}`,
4814
4814
  };
4815
4815
  console.log('当前lang请求状态异常,具体信息见', getRes);
4816
4816
  reject(getRes);
4817
4817
  }
4818
4818
  }
4819
4819
  };
4820
4820
  langXhrRequest.onerror = () => {
4821
4821
  const getRes = {
4822
4822
  ...info,
4823
4823
  env: getSgmCustomCode(langLoadErrorSgmCode),
4824
4824
  msg: '请求错误',
4825
4825
  };
4826
4826
  console.log('当前lang请求错误', getRes);
4827
4827
  langXhrRequest.abort();
4828
4828
  reject(getRes);
4829
4829
  };
4830
4830
  langXhrRequest.ontimeout = () => {
4831
4831
  const getRes = {
4832
4832
  ...info,
4833
4833
  msg: `请求${langXhrRequest.timeout}ms超时异常,状态${langXhrRequest.status}`,
4834
4834
  };
4835
4835
  console.log('执行lang多语言请求超时异常', getRes);
4836
4836
  langXhrRequest.abort();
4837
4837
  reject(getRes);
4838
4838
  };
4839
4839
  langXhrRequest.send();
4840
4840
  } catch (e) {
4841
4841
  console.log('执行lang多语言请求异常', e);
4842
4842
  reject({
4843
4843
  ...info,
4844
4844
  env: getSgmCustomCode(langLoadErrorSgmCode),
4845
4845
  msg: '未知异常',
4846
4846
  error: e,
4847
4847
  });
4848
4848
  }
4849
4849
  });
4850
4850
  }