iphone-xudale 0.2.9

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.
Files changed (62) hide show
  1. package/.eslintrc.json +3 -0
  2. package/app/(pages)/options/page.tsx +720 -0
  3. package/app/(pages)/popup/page.tsx +166 -0
  4. package/app/(pages)/tips/page.tsx +40 -0
  5. package/app/components/DropListBox.tsx +157 -0
  6. package/app/components/SVGPlay.tsx +14 -0
  7. package/app/favicon.ico +0 -0
  8. package/app/globals.css +27 -0
  9. package/app/layout.tsx +15 -0
  10. package/app/page.tsx +3 -0
  11. package/app/scripts/content/checkoutSteps.ts +341 -0
  12. package/app/scripts/content/doFroApplePages.ts +206 -0
  13. package/app/scripts/content/getPageInitInfo.ts +49 -0
  14. package/app/scripts/content/getStoreCanPickInfo.ts +251 -0
  15. package/app/scripts/content/goOrderSteps.ts +179 -0
  16. package/app/scripts/content/index.ts +56 -0
  17. package/app/scripts/content/playSystemNotifacation.ts +39 -0
  18. package/app/scripts/content/sendSelfNotificatioin.ts +27 -0
  19. package/app/scripts/inject/index.ts +18 -0
  20. package/app/shared/constants.ts +236 -0
  21. package/app/shared/interface.ts +25 -0
  22. package/app/shared/location/city.json +1774 -0
  23. package/app/shared/location/county.json +17115 -0
  24. package/app/shared/location/province.json +94 -0
  25. package/app/shared/util.ts +93 -0
  26. package/buildAfter.js +86 -0
  27. package/bunBuild.ts +54 -0
  28. package/extension/content-script.js +7 -0
  29. package/extension/favicon.ico +0 -0
  30. package/extension/icons/icon128.png +0 -0
  31. package/extension/icons/icon16.png +0 -0
  32. package/extension/icons/icon19-disable.png +0 -0
  33. package/extension/icons/icon19.png +0 -0
  34. package/extension/icons/icon32.png +0 -0
  35. package/extension/icons/icon38.png +0 -0
  36. package/extension/icons/icon48.png +0 -0
  37. package/extension/inject-script.js +1 -0
  38. package/extension/manifest.json +38 -0
  39. package/extension/service-worker.js +62 -0
  40. package/extension.next.config.js +25 -0
  41. package/icon_generator.py +30 -0
  42. package/middleware.ts +21 -0
  43. package/next.config.js +15 -0
  44. package/package.json +67 -0
  45. package/postcss.config.js +6 -0
  46. package/public/assets/images/SCR-20230916-nbkz.png +0 -0
  47. package/public/assets/images/SCR-20230916-nbyv.png +0 -0
  48. package/public/assets/images/SCR-20230916-ncte.png +0 -0
  49. package/public/assets/images/SCR-20230916-ndgw.png +0 -0
  50. package/public/assets/images/SCR-20230916-ndks.png +0 -0
  51. package/public/assets/images/SCR-20230916-neaa.png +0 -0
  52. package/public/assets/images/SCR-20230916-neeq.jpeg +0 -0
  53. package/public/assets/images/SCR-20230916-nfkt.png +0 -0
  54. package/public/assets/images/SCR-20230919-ulfn.png +0 -0
  55. package/public/assets/images/SCR-20230919-ulzd.png +0 -0
  56. package/public/assets/images/SCR-20230919-uocr.png +0 -0
  57. package/public/icon_original.png +0 -0
  58. package/public/next.svg +1 -0
  59. package/public/vercel.svg +1 -0
  60. package/tailwind.config.ts +20 -0
  61. package/tsconfig.json +27 -0
  62. package/types/global.d.ts +19 -0
@@ -0,0 +1,341 @@
1
+ import { IPHONEORDER_CONFIG, VOICE_OBJ } from '@/app/shared/interface'
2
+ import { fetchHeaders, defaultAres, CHECKOUT_STEPS } from '@/app/shared/constants'
3
+ import crossfetch from 'cross-fetch'
4
+ import sendSelfNotificatioin from './sendSelfNotificatioin'
5
+ import playSystemNotification from './playSystemNotifacation'
6
+ import { each as _each, map as _map, find as _find, isEmpty as _isEmpty, keys as _keys } from 'lodash'
7
+ const fetch = crossfetch.bind(this)
8
+
9
+ interface ICheckoutStepsProps {
10
+ step: string
11
+ x_aos_stk: string
12
+ stepInfo: Record<string, any>
13
+ iPhoneOrderConfig: IPHONEORDER_CONFIG
14
+ noNeedTimeSlot?: boolean
15
+ }
16
+
17
+ const checkoutSteps = async ({ step, x_aos_stk, stepInfo, iPhoneOrderConfig, noNeedTimeSlot }: ICheckoutStepsProps) => {
18
+ const { host, protocol } = window.location || {}
19
+ const districtName = iPhoneOrderConfig.districtName || defaultAres.districtName
20
+ const provinceName = iPhoneOrderConfig.provinceName || defaultAres.provinceName
21
+ const cityName = iPhoneOrderConfig.cityName || defaultAres.cityName
22
+ const provinceCityDistrict =
23
+ provinceName == cityName ? cityName + ' ' + districtName : provinceName + ' ' + cityName + ' ' + districtName
24
+ let url = `${protocol}//${host}/shop/checkoutx` // checkout.fulfillment`
25
+
26
+ let data = [],
27
+ result,
28
+ resJson,
29
+ dataString: string
30
+ let options = {
31
+ method: 'POST',
32
+ headers: {
33
+ ...fetchHeaders,
34
+ 'X-Aos-Model-Page': 'checkoutPage',
35
+ 'X-Aos-Stk': x_aos_stk,
36
+ referrer: `${protocol}//${host}/shop/checkout?_s=Fulfillment-init`,
37
+ },
38
+ credentials: 'include' as RequestCredentials,
39
+ }
40
+
41
+ if (noNeedTimeSlot && step == CHECKOUT_STEPS.checkoutFulfillment) {
42
+ console.log(`this step is`, `checkoutFulfillment`)
43
+ url += step
44
+
45
+ const { storeNumber, district = districtName } = stepInfo || {}
46
+ data = [
47
+ `checkout.fulfillment.fulfillmentOptions.selectFulfillmentLocation=RETAIL`,
48
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.showAllStores=false`,
49
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.selectStore=${storeNumber}`,
50
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.searchInput=${encodeURIComponent(
51
+ provinceName + ' ' + cityName + ' ' + district
52
+ )}`,
53
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.city=${encodeURIComponent(
54
+ cityName
55
+ )}`,
56
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.state=${encodeURIComponent(
57
+ provinceName
58
+ )}`,
59
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.provinceCityDistrict=${encodeURIComponent(
60
+ provinceCityDistrict
61
+ )}`,
62
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.countryCode=CN`,
63
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.district=${encodeURIComponent(
64
+ district
65
+ )}`,
66
+ ]
67
+ dataString = data.join(`&`)
68
+ result = await fetch(url, {
69
+ ...options,
70
+ body: dataString,
71
+ })
72
+ resJson = await result.json()
73
+ console.log(`resJson`, resJson)
74
+ const { pickupContact } = resJson?.body?.checkout || {}
75
+ const { status } = resJson?.head || {}
76
+ const isSuccess = status == 200
77
+ return { isSuccess, pickupContact }
78
+ }
79
+
80
+ if (step == CHECKOUT_STEPS.selectStore) {
81
+ console.log(`this step is`, `selectStore`)
82
+ url += step
83
+
84
+ const { storeNumber, district = districtName } = stepInfo || {}
85
+ data = [
86
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.showAllStores=false`,
87
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.selectStore=${storeNumber}`,
88
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.searchInput=${encodeURIComponent(
89
+ provinceName + ' ' + cityName + ' ' + district
90
+ )}`,
91
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.city=${encodeURIComponent(
92
+ cityName
93
+ )}`,
94
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.state=${encodeURIComponent(
95
+ provinceName
96
+ )}`,
97
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.provinceCityDistrict=${encodeURIComponent(
98
+ provinceCityDistrict
99
+ )}`,
100
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.countryCode=CN`,
101
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.district=${encodeURIComponent(
102
+ district
103
+ )}`,
104
+ ]
105
+ dataString = data.join(`&`)
106
+ result = await fetch(url, {
107
+ ...options,
108
+ body: dataString,
109
+ })
110
+ resJson = await result.json()
111
+ console.log(`resJson`, resJson)
112
+ const { fulfillment } = resJson?.body?.checkout || {}
113
+ const noNeedTimeSlot = _isEmpty(fulfillment?.pickupTab?.pickup?.timeSlot)
114
+ const { pickUpDates, timeSlotWindows } = fulfillment?.pickupTab?.pickup?.timeSlot?.dateTimeSlots?.d || {}
115
+
116
+ if (!noNeedTimeSlot && _isEmpty(timeSlotWindows)) return { isSuccess: false }
117
+
118
+ let dayRadio,
119
+ selectTimeSLot: Record<string, any> = {}
120
+ _each(timeSlotWindows, (timeSlotWindowItem, selectedIndex) => {
121
+ selectTimeSLot = {}
122
+ dayRadio = _keys(timeSlotWindowItem)?.[0]
123
+ let timeSlotLit = timeSlotWindowItem[dayRadio] || []
124
+ if (timeSlotLit?.length) {
125
+ selectTimeSLot = _find(timeSlotLit, timeSlot => {
126
+ return (
127
+ timeSlot?.Label &&
128
+ (/^12\:/.test(timeSlot.Label) || /^19\:/.test(timeSlot.Label) || /^20\:/.test(timeSlot.Label))
129
+ )
130
+ })
131
+
132
+ if (!selectTimeSLot) {
133
+ selectTimeSLot = timeSlotLit[Math.floor((timeSlotLit.length * 7) / 8)]
134
+ }
135
+ if (pickUpDates[selectedIndex]?.date && pickUpDates[selectedIndex]?.date.indexOf(dayRadio) > -1) {
136
+ selectTimeSLot.date = pickUpDates[selectedIndex]?.date
137
+ } else {
138
+ let now = new Date()
139
+ selectTimeSLot.date = [
140
+ now.getFullYear(),
141
+ now.getMonth() < 10 ? `0${now.getMonth()}` : now.getMonth(),
142
+ dayRadio,
143
+ ].join('-')
144
+ }
145
+
146
+ selectTimeSLot.dayRadio = dayRadio
147
+ return false
148
+ }
149
+ })
150
+
151
+ return {
152
+ pickUpDates,
153
+ timeSlotWindows,
154
+ timeSlot: selectTimeSLot,
155
+ noNeedTimeSlot,
156
+ isSuccess: noNeedTimeSlot || !_isEmpty(selectTimeSLot),
157
+ }
158
+ }
159
+ if (step == CHECKOUT_STEPS.selectPickupTime) {
160
+ console.log(`this step is`, `selectPickupTime`)
161
+ url += step
162
+ const {
163
+ storeNumber,
164
+ district = districtName,
165
+ checkInStart,
166
+ checkInEnd,
167
+ date,
168
+ SlotId,
169
+ signKey,
170
+ timeZone,
171
+ timeSlotValue,
172
+ dayRadio,
173
+ isRestricted,
174
+ } = stepInfo || {}
175
+
176
+ data = [
177
+ `checkout.fulfillment.fulfillmentOptions.selectFulfillmentLocation=RETAIL`,
178
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.showAllStores=false`,
179
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.selectStore=${storeNumber}`,
180
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.searchInput=${encodeURIComponent(
181
+ provinceName + ' ' + cityName + ' ' + district
182
+ )}`,
183
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.city=${encodeURIComponent(
184
+ cityName
185
+ )}`,
186
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.state=${encodeURIComponent(
187
+ provinceName
188
+ )}`,
189
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.provinceCityDistrict=${encodeURIComponent(
190
+ provinceCityDistrict
191
+ )}`,
192
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.countryCode=CN`,
193
+ `checkout.fulfillment.pickupTab.pickup.storeLocator.address.stateCitySelectorForCheckout.district=${encodeURIComponent(
194
+ district
195
+ )}`,
196
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.startTime=${encodeURIComponent(
197
+ checkInStart
198
+ )}`, // checkInStart = "01:00 PM",
199
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.displayEndTime=`,
200
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.isRecommended=false`,
201
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.endTime=${encodeURIComponent(checkInEnd)}`, // endTime = '01:15 PM',
202
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.date=${encodeURIComponent(date)}`, // data = '2022-09-23',
203
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.timeSlotId=${encodeURIComponent(SlotId)}`,
204
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.signKey=${encodeURIComponent(signKey)}`,
205
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.timeZone=${encodeURIComponent(timeZone)}`,
206
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.timeSlotValue=${encodeURIComponent(
207
+ timeSlotValue
208
+ )}`, // 23-13:00-13:15`,
209
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.dayRadio=${dayRadio}`, // dayRadio = 23
210
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.isRestricted=${
211
+ isRestricted ? String(isRestricted) : ''
212
+ }`,
213
+ `checkout.fulfillment.pickupTab.pickup.timeSlot.dateTimeSlots.displayStartTime=`,
214
+ ]
215
+ dataString = data.join(`&`)
216
+ result = await fetch(url, {
217
+ ...options,
218
+ body: dataString,
219
+ })
220
+ resJson = await result.json()
221
+ const { status } = resJson?.head || {}
222
+ const isSuccess = status == 200
223
+ return { isSuccess }
224
+ }
225
+ if (step == CHECKOUT_STEPS.pickupContact) {
226
+ console.log(`this step is`, `pickupContact`)
227
+ url += step
228
+ const { lastName, firstName, emailAddress, fullDaytimePhone, nationalIdSelf } = stepInfo || {}
229
+ data = [
230
+ `checkout.pickupContact.selfPickupContact.selfContact.address.lastName=${encodeURIComponent(lastName)}`,
231
+ `checkout.pickupContact.selfPickupContact.selfContact.address.firstName=${encodeURIComponent(firstName)}`,
232
+ `checkout.pickupContact.selfPickupContact.selfContact.address.emailAddress=${encodeURIComponent(
233
+ emailAddress
234
+ )}`,
235
+ `checkout.pickupContact.selfPickupContact.selfContact.address.fullDaytimePhone=${fullDaytimePhone}`,
236
+ `checkout.pickupContact.selfPickupContact.nationalIdSelf.nationalIdSelf=${nationalIdSelf}`,
237
+ `checkout.pickupContact.eFapiaoSelector.selectFapiao=none`,
238
+ ]
239
+ dataString = data.join(`&`)
240
+ result = await fetch(url, {
241
+ ...options,
242
+ body: dataString,
243
+ })
244
+ resJson = await result.json()
245
+ const { status } = resJson?.head || {}
246
+
247
+ const { billing } = resJson?.body?.checkout || {}
248
+ const { billingOptions } = billing || {}
249
+ const allBillingOptions = billingOptions?.d?.options || []
250
+
251
+ const isSuccess = status == 200
252
+ return {
253
+ isSuccess,
254
+ allBillingOptions,
255
+ }
256
+ }
257
+
258
+ if (step == CHECKOUT_STEPS.selectBill) {
259
+ console.log(`this step is`, `selectBill`)
260
+ url += step
261
+ const { billOption, billInstallment } = stepInfo || {}
262
+ data = [
263
+ `checkout.billing.billingOptions.selectBillingOption=${billOption}`, // ALIPAY
264
+ `checkout.locationConsent.locationConsent=true`,
265
+ ]
266
+ if (!isNaN(billInstallment)) {
267
+ // data.splice(1, 0, "3234")
268
+ data.splice(
269
+ 1,
270
+ 0,
271
+ `checkout.billing.billingOptions.selectedBillingOptions.installments.installmentOptions.selectInstallmentOption=${billInstallment}`
272
+ )
273
+ }
274
+ dataString = data.join(`&`)
275
+ result = await fetch(url, {
276
+ ...options,
277
+ body: dataString,
278
+ })
279
+ resJson = await result.json()
280
+ const { status } = resJson?.head || {}
281
+ const { billing } = resJson?.body?.checkout || {}
282
+ const isSuccess = status == 200
283
+ const installmentOptions =
284
+ billing?.billingOptions?.selectedBillingOptions?.installments?.installmentOptions?.d?.options || []
285
+ return {
286
+ isSuccess,
287
+ installmentOptions,
288
+ }
289
+ }
290
+
291
+ if (step == CHECKOUT_STEPS.checkoutBill) {
292
+ console.log(`this step is`, `checkoutBill`)
293
+ url += step
294
+ const { billOption, billInstallment } = stepInfo || {}
295
+ data = [
296
+ `checkout.billing.billingOptions.selectBillingOption=${billOption}`, // ALIPAY
297
+ ]
298
+ if (billInstallment > 0) {
299
+ data.push(
300
+ `checkout.billing.billingOptions.selectedBillingOptions.installments.installmentOptions.selectInstallmentOption=${billInstallment}`
301
+ )
302
+ }
303
+
304
+ dataString = data.join(`&`)
305
+ result = await fetch(url, {
306
+ ...options,
307
+ body: dataString,
308
+ })
309
+ resJson = await result.json()
310
+ const { status } = resJson?.head || {}
311
+ const isSuccess = status == 200
312
+ return { isSuccess }
313
+ }
314
+
315
+ if (step == CHECKOUT_STEPS.placeOrder) {
316
+ console.log(`this step is`, `placeOrder`)
317
+ url += step
318
+ result = await fetch(url, {
319
+ ...options,
320
+ })
321
+ resJson = await result.json()
322
+ const { status, data } = resJson?.head || {}
323
+ const isSuccess = status == 200 || status == 302 || status == 301 || false
324
+ if (isSuccess) {
325
+ try {
326
+ let text = encodeURIComponent(`抢到了!!!快去付钱\r\n账号:${iPhoneOrderConfig.appleId || ''}`)
327
+ // TODO send message by API
328
+ await playSystemNotification({ voiceInfo: iPhoneOrderConfig.voiceInfo })
329
+ await sendSelfNotificatioin({ url: iPhoneOrderConfig.selfNotiAPI })
330
+ } catch (e) {
331
+ console.log(`GMfetch error`)
332
+ }
333
+ }
334
+ return {
335
+ isSuccess,
336
+ url: data?.url || '',
337
+ }
338
+ }
339
+ }
340
+
341
+ export default checkoutSteps
@@ -0,0 +1,206 @@
1
+ import { sleep, changeInputValue, getElemByID } from '@/app/shared/util'
2
+ import {
3
+ applePageUrl,
4
+ pageElementsId,
5
+ storeKeys,
6
+ prefixBillingoptions,
7
+ iframeMessagePass,
8
+ } from '@/app/shared/constants'
9
+ import type { IPHONEORDER_CONFIG } from '@/app/shared/interface'
10
+ import getPageInitInfo from './getPageInitInfo'
11
+ import goOrderSteps from './goOrderSteps'
12
+ import { mapValues as _mapValues } from 'lodash'
13
+ import { restoreFromStorage } from '@/app/shared/util'
14
+
15
+ // let iPhoneOrderConfig: IPHONEORDER_CONFIG = {
16
+ // lastName: undefined,
17
+ // firstName: undefined,
18
+ // mobile: undefined,
19
+ // last4code: undefined,
20
+ // appleId: undefined, // same as email
21
+ // password: undefined,
22
+ // stepWait: 10,
23
+ // // @ts-ignore
24
+ // payBill: billTypeKeys.alipay,
25
+ // payInstallment: 0,
26
+ // cityName: undefined,
27
+ // districtName: undefined,
28
+ // provinceName: undefined,
29
+ // employeeId: undefined,
30
+ // }
31
+
32
+ const doFroApplePages = async (url?: string) => {
33
+ const orderEnabled = !!(await restoreFromStorage(storeKeys.orderEnabled))
34
+ console.log(`orderEnabled in doForApplePages`, orderEnabled)
35
+ let iframeContainer = document?.getElementById(iframeMessagePass.iframeID) as HTMLIFrameElement
36
+ if (!orderEnabled) {
37
+ if (iframeContainer) {
38
+ iframeContainer.style.display = 'none'
39
+ }
40
+ return
41
+ }
42
+
43
+ if (iframeContainer) {
44
+ iframeContainer.style.display = ''
45
+ }
46
+
47
+ const iPhoneOrderConfig: IPHONEORDER_CONFIG = await restoreFromStorage(storeKeys.orderConfig)
48
+ await sleep(0.5)
49
+
50
+ let queryString = new URLSearchParams(location.search.toLowerCase())
51
+ let pathname = location.pathname
52
+ console.log(`doFroApplePages`, queryString)
53
+
54
+ const { checkout: checkoutElems, shoppingCart: shoppingCartElems, signIn: signInElems } = pageElementsId
55
+
56
+ // 登陆态过期,直接去购物车页
57
+ if (/\/shop\/sorry/i.test(pathname)) {
58
+ location.href = applePageUrl.shoppingCart
59
+ return
60
+ }
61
+
62
+ // 在购物车页面
63
+ if (/\/shop\/bag/i.test(pathname)) {
64
+ let goCheckoutBtn: HTMLElement | null = getElemByID(shoppingCartElems.checkoutButton)
65
+ if (!goCheckoutBtn && url) {
66
+ location.href = url
67
+ return
68
+ }
69
+ // await sleep(Math.random() * 2)
70
+ goCheckoutBtn?.click()
71
+ return
72
+ }
73
+
74
+ // 在登陆页
75
+ if (/\/signin/i.test(pathname)) {
76
+ if (getElemByID(signInElems.dataHandleByAppleCheckbox)) {
77
+ const dataHandleByAppleCheckbox = getElemByID(signInElems.dataHandleByAppleCheckbox) as HTMLInputElement
78
+ const dataOutSideMyCountryCheckbox = getElemByID(
79
+ signInElems.dataOutSideMyCountryCheckbox
80
+ ) as HTMLInputElement
81
+ dataHandleByAppleCheckbox.click()
82
+ dataHandleByAppleCheckbox.checked = true
83
+ dataOutSideMyCountryCheckbox.click()
84
+ dataOutSideMyCountryCheckbox.checked = true
85
+ getElemByID(signInElems.acceptButton)?.click()
86
+ await sleep(0.5)
87
+ }
88
+
89
+ if (iPhoneOrderConfig.appleId && iPhoneOrderConfig.password) {
90
+ let addIdDom = getElemByID(signInElems.appleIdInput) as HTMLInputElement
91
+ let addCodeDom = getElemByID(signInElems.applePasswordInput) as HTMLInputElement
92
+ let goLoginBtn = getElemByID(signInElems.loginSubmitButton)
93
+ if (addIdDom && addCodeDom && goLoginBtn) {
94
+ changeInputValue(addIdDom, iPhoneOrderConfig.appleId)
95
+ changeInputValue(addCodeDom, iPhoneOrderConfig.password)
96
+ goLoginBtn.click()
97
+ }
98
+ } else {
99
+ // 没有账号信息就以游客登录
100
+ let guestLoginBtn = getElemByID(signInElems.guestLoginButon)
101
+ if (guestLoginBtn) {
102
+ console.log(`click guestLoginBtn`, guestLoginBtn)
103
+ guestLoginBtn.click()
104
+ }
105
+ }
106
+ return
107
+ }
108
+
109
+ if (/\/shop\/checkout/.test(pathname)) {
110
+ console.log(`I am in checkout steps`)
111
+ const s_value = queryString.get('_s') || ''
112
+ // 选择门店
113
+ if (s_value.includes('fulfillment')) {
114
+ let iwantpickup = getElemByID(checkoutElems.fulfillment.selectPickupButton)
115
+ if (!iwantpickup && url) {
116
+ location.href = url
117
+ return
118
+ }
119
+ iwantpickup?.click()
120
+
121
+ let pageInfo = await getPageInitInfo()
122
+ const { partNumber, x_aos_stk } = pageInfo || {}
123
+ console.log(`partNumber, x_aos_stk`, partNumber, x_aos_stk)
124
+ if (!partNumber || !x_aos_stk) {
125
+ // 当前页面没有信息, 则刷新一下
126
+ await sleep(iPhoneOrderConfig.stepWait, 'wait and reload')
127
+ location.reload()
128
+ return
129
+ } else {
130
+ await goOrderSteps({
131
+ partNumber,
132
+ x_aos_stk,
133
+ iPhoneOrderConfig,
134
+ })
135
+ }
136
+ }
137
+
138
+ // 填写取货信息,个人信息 页面
139
+ if (s_value.includes('pickupcontact')) {
140
+ let checkoutSelectPrefix = `checkout.pickupContact.selfPickupContact.selfContact.address`
141
+
142
+ let lastNameDom = getElemByID(checkoutElems.pickupContact.lastName) as HTMLInputElement,
143
+ firstNameDom = getElemByID(checkoutElems.pickupContact.firstName) as HTMLInputElement,
144
+ emailAddressDom = getElemByID(checkoutElems.pickupContact.emailAddress) as HTMLInputElement,
145
+ mobileDom = getElemByID(checkoutElems.pickupContact.mobile) as HTMLInputElement,
146
+ last4IdDom = getElemByID(checkoutElems.pickupContact.last4Id) as HTMLInputElement
147
+ // 如果当前dom不存在,说明此时页面还没有加载出来,直接刷新页面加载
148
+ if (!lastNameDom && url) {
149
+ location.href = url
150
+ return
151
+ }
152
+ changeInputValue(lastNameDom, iPhoneOrderConfig.lastName)
153
+ changeInputValue(firstNameDom, iPhoneOrderConfig.firstName)
154
+ changeInputValue(emailAddressDom, iPhoneOrderConfig.appleId)
155
+ changeInputValue(mobileDom, iPhoneOrderConfig.mobile)
156
+ changeInputValue(last4IdDom, iPhoneOrderConfig.last4code)
157
+ getElemByID(checkoutElems.continuebutton)?.click()
158
+ // document.querySelector(`#rs-checkout-continue-button-bottom`).click()
159
+ return
160
+ }
161
+
162
+ // 选择付款方式页面
163
+ if (s_value.includes('billing')) {
164
+ const { payBill, payInstallment } = iPhoneOrderConfig || {}
165
+ let alipayBtnInput = getElemByID(checkoutElems.bill.alipay)
166
+ let payBillBtnInput = getElemByID(checkoutElems.bill[payBill])
167
+ if (payBillBtnInput) {
168
+ payBillBtnInput.click()
169
+
170
+ if (!['wechat', 'alipay'].includes(payBill)) {
171
+ // 有分期需求
172
+ await sleep(1.5)
173
+ const dataAutom = `${payBillBtnInput.id}-${payInstallment}`.replace(`${prefixBillingoptions}.`, '')
174
+ const payInstallmentBtnInput = document.querySelector(`input[data-autom="${dataAutom}"]`)
175
+ console.log(`payInstallmentBtnInput`, payInstallmentBtnInput, `input[data-autom="${dataAutom}"]`)
176
+ ;(payInstallmentBtnInput as HTMLInputElement)?.click()
177
+ }
178
+ } else if (alipayBtnInput) {
179
+ // 获取不到就走默认的支付宝
180
+ alipayBtnInput.click()
181
+ } else if (url) {
182
+ // 如果没有支付宝,说明页面加载没好,直接刷新
183
+ location.href = url
184
+ return
185
+ }
186
+ getElemByID(checkoutElems.continuebutton)?.click()
187
+ return
188
+ }
189
+
190
+ // 结账review页面
191
+ if (s_value.includes('review')) {
192
+ let orderBtn = getElemByID(checkoutElems.continuebutton)
193
+ if (orderBtn) {
194
+ orderBtn.click()
195
+ } else if (url) {
196
+ // 如果既没有去支付按钮,说明页面加载没好,直接刷新
197
+ location.href = url
198
+ return
199
+ }
200
+
201
+ return
202
+ }
203
+ }
204
+ }
205
+
206
+ export default doFroApplePages
@@ -0,0 +1,49 @@
1
+ import crossfetch from 'cross-fetch'
2
+ import { applePageUrl } from '@/app/shared/constants'
3
+ import { commonHeaders } from '@/app/shared/constants'
4
+
5
+ // fix TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
6
+ const fetch = crossfetch.bind(this)
7
+
8
+ const getPageInitInfo = async () => {
9
+ let partNumber, x_aos_stk
10
+ const initData = document.getElementById('init_data')?.textContent
11
+ const initDataJson: Record<string, any> = initData ? JSON.parse(initData) : {}
12
+ const { meta, checkout } = initDataJson || {}
13
+ x_aos_stk = meta?.h?.['x-aos-stk']
14
+
15
+ const checkoutPickUpItems = checkout?.fulfillment?.pickupTab?.pickup?.items || {}
16
+ // console.log(`checkoutPickUpItems`, checkoutPickUpItems)
17
+ const firstC = checkoutPickUpItems?.c?.[0] || ''
18
+ if (firstC) {
19
+ const firstItemInfo = checkoutPickUpItems[firstC] || {}
20
+ const baseInfo = firstItemInfo.d || {}
21
+ const productEvar1 = baseInfo?.productEvar1?.split('|')
22
+ partNumber = productEvar1?.length && productEvar1[productEvar1.length - 1]
23
+ }
24
+
25
+ if (!partNumber) {
26
+ let shopBagResText = ''
27
+ try {
28
+ let headers: any = { ...commonHeaders }
29
+ delete headers.referer
30
+ const shopBagRes = await fetch(applePageUrl.shoppingCartWithoutHost, {
31
+ headers: headers,
32
+ credentials: 'include',
33
+ })
34
+ shopBagResText = await shopBagRes.text()
35
+ } catch (e) {
36
+ console.log(`fetch error`, e)
37
+ }
38
+
39
+ partNumber = shopBagResText?.match(/(?<=productEvar1\"\:"Cart\|\|)([a-zA-Z0-9]+\/A)/g)?.[0]
40
+ }
41
+
42
+ // console.log(`partNumber`, partNumber)
43
+ return {
44
+ partNumber,
45
+ x_aos_stk,
46
+ }
47
+ }
48
+
49
+ export default getPageInitInfo