@conecli/cone-render 0.8.20-shop.124 → 0.8.20-shop.125

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