iphone-xudale 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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