PageSourceSearch

https://www.sinoevsetech.com/assets/js/unit/cart.js

js sinoevsetech.com collected 2026-10-04 04:36:11 UTC 48,169 bytes, 1,106 lines download raw bytes

1class ScriptCart extends Script {
2  constructor(params) {
3    super(params)
4    this.utilts = Utilts.ins()
5    this.popstateInit = null
6  }
7  /** 初始化,支持异步 */
8  async init() {
9    const baseBath = '/assets/js/unit/common'
10    await new Load('/assets/plugins/vue.min.js', 'application/javascript', {version_enabled: true})
11    // await new Load(`${baseBath}/cartApi.js`)
12    // await new Load(`${baseBath}/priceManager.js`)
13    // await new Load(`${baseBath}/cartManager.js`)
14    // await new Load(`${baseBath}/cartOrderManager.js`)
15    // await new Load(`${baseBath}/addressManager.js`)
16    // await new Load(`${baseBath}/orderSummary.js`)
17    // await new Load(`${baseBath}/cartUtilts.js`)
18    // await new Load(`${baseBath}/paypal_sdk.js`)
19    // await new Load(`${baseBath}/airwallex_sdk.js`)
20    // await new Load('/assets/plugins/selector.js')
21    // await new Load('/assets/plugins/country.js')
22    const promises = [
23      `${baseBath}/cartApi.js`,
24      `${baseBath}/priceManager.js`,
25      `${baseBath}/cartManager.js`,
26      `${baseBath}/cartOrderManager.js`,
27      `${baseBath}/addressManager.js`,
28      `${baseBath}/orderSummary.js`,
29      `${baseBath}/cartUtilts.js`,
30      `${baseBath}/paypal_sdk.js`,
31      `${baseBath}/airwallex_sdk.js`,
32      '/assets/plugins/selector.js',
33      '/assets/plugins/country.js'
34    ]
35    await Promise.all(promises.map(file => new Load(file, 'application/javascript', {version_enabled: true})))
36    this.cartManager = CartManager.ins()
37    this.initVue()
38
39    // 非苹果内核浏览器执行回退
40    if(!(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))) {
41      let beforeHref = window.location.href
42      this.popstateInit = () => {
43        if (window.location.search && beforeHref === window.location.href) {
44          history.go(-2)
45        }
46        beforeHref = window.location.href
47        window.location.reload()
48      }
49      window.addEventListener('popstate', this.popstateInit, false)
50    }
51
52    // 失败时访问统计
53    if (window.location.search.includes('payment_status=fail')) window.app.info.utilts.postVisitor()
54
55  }
56  /** 购物车,支付,物流,相关操作 */
57  initVue() {
58    const _that = this
59    new Vue({
60      el: `#${this.attrId} .unit-cart__app`,
61      mixins: [
62        this.cartManager.cartData,
63        this.cartManager.addressManager,
64        this.cartManager.cartUtilts,
65        this.cartManager.cartOrderManager,
66        this.cartManager.orderSummary
67      ],
68      created() {
69        this.init()
70      },
71      mounted() {
72        document.addEventListener('click', () => {
73          if (this.showSelectCoupon) this.showSelectCoupon = false
74        })
75      },
76      computed: {
77        isOrderDisable: {
78          get() {
79            let bool = false
80            if (this.step === 2) {
81              Object.keys(this.order_product).forEach(key => {
82                const data = this.order_product[key]
83                data.resultData.forEach(val => {
84                  if (val.datas?.length > 0 && val.logistics?.length < 1 && key !== 'free') bool = true
85                })
86                // if (data.products.length > 0 && data.logistics.length < 1 && key !== 'free') bool = true
87              })
88            }
89            return bool
90          }
91        },
92        /** 订单数 */
93        orderAmount: {
94          get() {
95            let num = 0
96            Object.keys(this.order_product).forEach(key => {
97              if (this.order_product[key].products.length > 0) num++
98            })
99            return num
100          }
101        },
102        /** 订单总数小于1000w */
103        orderTotalPrice: {
104          get() {
105            // 总价格
106            const allProductPrice = this.selected_pro_price
107            // 总价格加上运费
108            let price = allProductPrice + this.logistics_price
109            // 总价格减去优惠券
110            price = price - this.selected_coupon_price
111            // 总价减去优惠码的价格
112            price = price - this.selected_code_price
113            // 总价格减去限时折扣
114            if (this.order_id) price = price - this.selected_discount_price
115            // 总价格减去限时折扣
116            price = price - this.selected_reduction_price
117            price += this.surcharge_price
118            if (price <= 0) return 0
119            const total = this.utilts.toFixed(price)
120            return total
121          }
122        }
123      },
124      /** 游客修改国家/城市,更新物流 */
125      watch: {
126        step(_val, _oldVal) {
127          const info = this.payType.find(p => p.type === 11)
128          if (info) this.initPaypal()
129          const airwallexinfo = this.payType.find(p => p.type === 19)
130          if (airwallexinfo) this.initAirwallex()
131          // 未登录的情况下初始化国家/省份信息
132          if (!window.app.info.user.is_login && _val === 2) {
133            this.$nextTick(() => this.initAddressSelect())
134          }
135        },
136        'formData.country_id': {
137          handler: function (country_id) {
138            if (country_id) {
139              this.shipment_params.country_id = country_id
140              this.shipment_params.province_id = this.formData.province_id
141              if (!window.app.info.user.is_login) this.getShippingInfo()
142            }
143          },
144        },
145        'formData.province_id': {
146          handler: function (province_id) {
147            if (province_id) {
148              this.shipment_params.country_id = this.formData.country_id
149              this.shipment_params.province_id = province_id
150              if (!window.app.info.user.is_login) this.getShippingInfo()
151            }
152          },
153        },
154      },
155      methods: {
156        async init() {
157          // hash 购物车和下单
158          this.cartListLoading = true
159          await this.getPayType() // 获取支付方式
160          this.isBuyNow()
161          // 判断是否是搭配产品一起购买,如果是就从sessionStorage里获取搭配的产品
162          this.isBuyTogether()
163          let matchProducts = []
164          if (this.is_buy_together) {
165            matchProducts = JSON.parse(sessionStorage.getItem('matchProducts') || '[]')
166          }
167          if (matchProducts.length) {
168            this.matchProducts = matchProducts
169          }
170          this.isMoblie()
171          const is_login = window.app.info.user.is_login
172          // 获取下单地址
173          if (is_login) { await this.getAddressList() }
174          // 获取购物车信息 - 先检查购买途径
175          if (this.is_buy_now || this.is_buy_together) {
176            await this.initCheckoutConfig() //各种判断检查条件
177            await this.getNowProductDetail()
178            //获取登录用户地址,不要放外面会有加载顺序bug
179            if (is_login) {
180              await this.initCountry();
181              await this.getAddressList();
182            }
183            await this.initCoupons()
184            await this.getConupoList()
185          } else {
186            //各种判断检查条件,不要放外面会有加载顺序bug
187            await this.initCheckoutConfig()
188            //获取登录用户地址,不要放外面会有加载顺序bug
189            if (is_login) {
190              await this.initCountry();
191              await this.getAddressList();
192            }
193            this.order_id = this.utilts.getQuery('id') || 0
194            this.order_id = Number(this.order_id)
195            if (this.order_id) {
196              // 未登录时取消返回提示
197              if (!is_login) {
198                const cancel = this.utilts.getParamsByUrl('err')
199                if (cancel === 'cancel') {
200                  const tip = `The order has been generated and can be viewed after registration and login. Or you can re-order directly.`
201                  new Message().info(this.utilts.$t(tip), 6)
202                }
203              }
204              await this.changeOrder(Number(this.order_id)) // 修改订单
205            }
206            else {
207              window.history.pushState('', '', `cart.html`);
208              await this.cartList() // 获取购物车列表
209              this.initCoupons()
210            }
211          }
212          this.cartListLoading = false
213        },
214        // 立刻购买方式-获取产品详情
215        async getNowProductDetail() {
216          const price_id = this.utilts.getParamsByUrl('price_id') || 0
217          const quantity = this.utilts.getParamsByUrl('quantity') || 0
218          let match_price_ids = ''
219          let ids = this.matchProducts.map(el => el.price_id)
220          if (this.is_buy_together) {
221            match_price_ids = ids.join(',')
222          }
223          const data = await this.api.getShopingBuy(price_id, quantity, match_price_ids)
224          this.$set(this, 'cart_list', data)
225          this.$set(this, 'selected_pro', data)
226          this.updateCartAllPrice()
227          // 获取订单详情
228          this.cartNextStep()
229        },
230        /**获取购物车列表 */
231        async cartList() {
232          const data = await this.api.getShoppingCard()
233          if (data && data.length > 0) {
234            this.$set(this, 'cart_list', data)
235            this.$set(this, 'selected_pro', data)
236            this.updateCartAllPrice()
237            this.getConupoList()
238            this.setCountTime()
239          }
240        },
241        /**
242         * 下单流程
243         * 第一步,选择购物车里物品进行下一步 购物车列表:1
244         * 第二步,生成订单,选择物流  地址&物流:2
245         */
246        async cartNextStep(event) {
247          if (!this.checkoutVisitor()) return
248          if (this.step === 1) this.initCartFirstStep(event)
249          else if (this.step === 2) this.initCartSecondStep(event)
250        },
251        /** 初始化购物车第一步 */
252        async initCartFirstStep(event) {
253          if (this.is_buy_now) {
254            const str = '&buy_source=buynow'
255            let url = `cart.html${window.location.search}`
256            if (window.location.search.indexOf(str) <= -1) url = `${url}${str}`
257            window.history.replaceState('', '', url)
258          } else if(this.is_buy_together){
259            const str = '&buy_source=buytogether'
260            let url = `cart.html${window.location.search}`
261            if (window.location.search.indexOf(str) <= -1) url = `${url}${str}`
262            window.history.replaceState('', '', url)
263          } else {
264            window.history.pushState('', '', `cart.html?buy_source=cart`);
265          }
266          window.app.info.utilts.postVisitor()
267          event = event || {}
268          this.utilts.setBtnLoadingStatus(event.target, true)
269          //异常状态:0-正常;1-产品下架;2-款式不存在;3-价格变化;4-无库存;5-库存不足
270          if (!this.selected_pro || this.selected_pro.length <= 0) {
271            this.utilts.setBtnLoadingStatus(event.target, false)
272            new Message().error(this.utilts.$t('You haven’t selected a product yet'))
273            return
274          }
275          // 检查下单合法性
276          const resData = await this.checkoutCartProduct()
277          // 不为0有问题提示
278          if (resData.status !== 0) {
279            this.utilts.setBtnLoadingStatus(event.target, false)
280            this.checkHint(resData)
281            return
282          }
283          // 购物车列表下单(非立刻购买方式)
284          if (!this.is_buy_now && this.selected_pro.length > 0) {
285            // 判断总价超过9999w时不给下单
286            if (this.orderTotalPrice > 40000000) {
287              this.utilts.setBtnLoadingStatus(event.target, false)
288              new Message().error(this.utilts.$t("A single order cannot exceed 4000W"))
289              return
290            }
291            // 判断产品是否下架
292            let bool = await this.checkProductStatus(this.selected_pro)
293            if (!bool) {
294              this.utilts.setBtnLoadingStatus(event.target, false)
295              const tip = "The product you selected has been taken off the shelf, please select again"
296              new Message().error(this.utilts.$t(tip))
297              return
298            }
299          }
300          // 提前渲染游客已存地址
301          if (!window.app.info.user.is_login && this.order_address) {
302            this.$set(this, 'formData', this.order_address)
303          }
304          /** 整理产品订单 */
305          this.initOrderProduct()
306          // 判断已选产品进入下一步选择物流操作, 否则提示未选产品
307          this.selected_pro.length ? this.step++ :
308            new Message().error(this.utilts.$t('You haven’t selected a product yet'))
309          this.utilts.setBtnLoadingStatus(event.target, false)
310          this.utilts.setGtag('begin_checkout')
311        },
312        /** 初始化购物车第二步 */
313        initCartSecondStep(event) {
314          return new Promise(async (resolve, _reject) => {
315            if (this.is_create_account) {
316              await this.changeCreateAccount()
317            }
318            const isOk = await this.checkOrderpaid(event)
319            if (!isOk) return
320            let coupon_member_id = this.getCouponMemberId()
321            let params = {
322              ...this.getCartOrderParams(),
323              order_remarks: this.order_remarks,
324              payment_id: this.payment_id,
325              serial_number: this.order_detail.serial_number || this.serial_number || '',
326              coupon_member_id,
327              attachments:this.attachments?JSON.stringify(this.attachments.map(item => {
328                return {
329                  name:item.name,
330                  url:item.url
331                }
332              })):''
333            }
334            if (this.is_create_account && !this.email_is_register && this.account_password) {
335              params.password = this.account_password
336            }
337            if (this.is_credit_card) {
338              const order_bill = this.setCreditCarBill()
339              if (order_bill) params = { ...params, order_bill }
340            }
341            if (this.is_buy_together) {
342              let match_price_ids = ''
343              let ids = this.matchProducts.map(el => el.price_id)
344              match_price_ids = ids.join(',')
345              params = {
346                ...params,
347                match_price_ids
348              }
349            }
350            this.utilts.setGtag('add_payment_info')
351            console.log('paramss', params);
352            const data = await this.setCartOrder(params)
353            resolve(data)
354
355          })
356        },
357        /**
358         * 获取coupon_member_id
359         * @returns
360         */
361        getCouponMemberId() {
362          let coupon_member_id = 0
363          if (this.couponInfo) { coupon_member_id = this.couponInfo.id || 0 }
364          else if (this.couponCode) { coupon_member_id = this.couponCode.id || 0 }
365          // 如果上面都没有coupon_member_id,就获取详情里面的order_product大于0的coupon_member_id
366          if (coupon_member_id === 0 && this.order_id) {
367            const products = this.order_detail.order_product
368            if (products.length > 0) {
369              const couponProduct = products.filter(p => p.coupon_member_id > 0)
370              if (couponProduct.length > 0) coupon_member_id = couponProduct[0].coupon_member_id
371            }
372          }
373          return coupon_member_id
374        },
375        checkOrderpaid(event) {
376          return new Promise(async (resolve, _reject) => {
377            event = event || {}
378            // 下单按钮
379            this.placeOrder = event.target
380            this.utilts.setBtnLoadingStatus(this.placeOrder, true)
381            const setBtnFalse = () => {
382              this.utilts.setBtnLoadingStatus(this.placeOrder, false)
383              resolve(null)
384              return false
385            }
386            // 是否可以发货
387            if (this.isOrderDisable) {
388              const tip = window.app.utilts.$t('This Supplier/Shipping Company does not deliver to your selected Country/Region.')
389              const tip2 = window.app.utilts.$t('Please fill in the delivery address before selecting the payment method')
390              const str = this.formData.country_id ? tip : tip2
391              new Message().error(this.utilts.$t(str))
392              return setBtnFalse()
393            }
394            // 检查游客是否能下单
395            if (!this.checkoutVisitor()) return setBtnFalse()
396
397            if (!this.checkOrder()) return setBtnFalse()
398            // 信用卡支付,检查填写的表单是否合法
399            const isCreditCheckForm = !this.is_same_address && !this.checkCreditFormData()
400            if (this.is_credit_card && isCreditCheckForm) return setBtnFalse()
401            // 信用卡支付需要传order_bill参数
402            if (this.is_credit_card) {
403              const order_bill = this.setCreditCarBill()
404              // 信用卡支付,检查邮件是否合法
405              if (!order_bill.email) {
406                new Message().error(this.utilts.$t('email format does not match'))
407                return setBtnFalse()
408              }
409            }
410            //异常状态:0-正常;1-产品下架;2-款式不存在;3-价格变化;4-无库存;5-库存不足
411            const resData = await this.checkoutCartProduct()
412            if (resData.status !== 0) {
413              this.checkHint(resData)
414              return setBtnFalse()
415            }
416            resolve(true)
417          })
418        },
419        /** paypai 完成支付回调 */
420        paypalCapture() {
421          return new Promise((resolve, _reject) => {
422            this.api.paypalCapture(this.paypal_order_id).then(res => {
423              resolve({ order_id: this.insert_order_id, data: res })
424            })
425          })
426        },
427        async calculateShippingCost2(data) {
428          const params = { ...this.getCartOrderParams() }
429          const resultData = await this.getShippingCost(params)
430          console.log('dataresultData', resultData);
431          this.logistics_price = (resultData?.shipping_price / 100)
432          this.surcharge_price = (resultData?.shipment_surcharge / 100)
433        },
434        calculateShippingCost(data) {
435          let totalCost = 0
436          let surchargeCost = 0
437          Object.keys(data).forEach(key => {
438            let selectedLogistics = []
439            data[key].resultData?.forEach(item => {
440              if (item.logistics) {
441                const selectedItems = item.logistics.filter(log => log.is_select)
442                selectedLogistics = selectedLogistics.concat(selectedItems)
443              }
444            })
445            let maxCostAdded = false
446            let idCount = {}
447            let tempShipment = {}
448            data[key].resultData?.forEach(item => {
449              item.logistics?.forEach(log => {
450                if (log.is_select) {
451                  const { id, calc_rule, shipment_cost, shipment_cost_range, surcharge_cost, all_surcharge } = log
452                  idCount[id] = (idCount[id] || 0) + 1
453                  if ((idCount[id] === 1 && all_surcharge === 1) || all_surcharge === 0) {
454                    surchargeCost += surcharge_cost
455                  }
456                  if (Array.isArray(shipment_cost_range)) {
457                    tempShipment[id] = {
458                      min_cost: 0,
459                      max_cost: 0,
460                      first_more_cost: 0,
461                      shipment_cost_range: 0
462                    }
463                    if (idCount[id] > 1) {
464                      if (calc_rule === 1) totalCost += shipment_cost
465                    } else {
466                      totalCost += shipment_cost
467                    }
468                  } else {
469                    if (idCount[id] > 1) {
470                      if (idCount[id] < 3) {
471                        if (calc_rule === 1) {
472                          totalCost += shipment_cost_range.single_more_cost
473                        } else{
474                          totalCost -= tempShipment[id].min_cost
475                          totalCost += tempShipment[id].max_cost
476                        }
477                      } else {
478                        if (calc_rule === 1) {
479                          totalCost += shipment_cost_range.single_more_cost
480                        }
481                      }
482                    } else {
483                      tempShipment[id] = shipment_cost_range
484                      totalCost += shipment_cost_range[calc_rule === 1 ? 'first_more_cost' : 'min_cost'] || 0
485                    }
486                  }
487                }
488              })
489            })
490          })
491          this.logistics_price = totalCost
492          this.surcharge_price = surchargeCost
493        },
494        /**选择物流 */
495        changeLogistics(data, type, shipment_method_ids) {
496          data.is_select = true
497          Object.keys(this.order_product).forEach(key => {
498            this.order_product[key].resultData.forEach(val => {
499              const currentLogistics = val.logistics ? JSON.parse(JSON.stringify(val.logistics)) : []
500              currentLogistics.forEach(item => {
501                if (key === type && shipment_method_ids === val.shipment_method_ids && data.id !== item.id) item.is_select = false
502                // if (item.is_select) num = Number(item.shipment_cost)
503              })
504              this.$set(val, 'logistics', currentLogistics)
505            })
506          })
507          this.calculateShippingCost2(this.order_product)
508        },
509        /**获取物流列表 */
510        getShippingList(json) {
511          return new Promise((resolve, reject) => {
512            if (!json.country_id) {
513              resolve([])
514              return
515            }
516            this.api.getShippingList(json)
517              .then(res => {
518                const data = res.data.map(item => {
519                  item.shipment_cost = Number((item.shipment_cost / 100).toFixed(2))
520                  if (!Array.isArray(item.shipment_cost_range)) {
521                    item.shipment_cost_range.max_cost = Number((item.shipment_cost_range.max_cost / 100).toFixed(2))
522                    item.shipment_cost_range.min_cost = Number((item.shipment_cost_range.min_cost / 100).toFixed(2))
523                    item.shipment_cost_range.first_more_cost = Number((item.shipment_cost_range.first_more_cost / 100).toFixed(2))
524                    item.shipment_cost_range.single_more_cost = Number((item.shipment_cost_range.single_more_cost / 100).toFixed(2))
525                  }
526                  item.surcharge_cost = Number((item.surcharge_cost / 100).toFixed(2))
527                  const num = item.shipment_reduction_amount | 0
528                  item.shipment_reduction_amount = Number((num / 100).toFixed(2))
529                  item.is_select = false
530                  return item
531                })
532                resolve(data)
533              })
534              .catch(err => reject(err))
535          })
536        },
537        getShippingCost(json) {
538          let ids = this.matchProducts.map(el => el.price_id)
539          if (this.is_buy_together) {
540            // match_price_ids = ids.join(',')
541            json.match_price_ids = ids.join(',')
542          }
543          return new Promise((resolve, reject) => {
544            this.api.getShippingCost(json)
545              .then(res => {
546                resolve(res.data)
547              })
548              .catch(err => reject(err))
549          })
550        },
551        resetProduct(data) {
552          const groupedData = data.reduce((acc, item) => {
553            const key = `${item.cart_product.shipment_ids}-${item.cart_product.shipment_method}`
554            if (!acc[key]) {
555              acc[key] = { shipment_method_ids: key, shipment_ids: item.cart_product.shipment_ids, shipment_method: item.cart_product.shipment_method, datas: [item] }
556            } else {
557              acc[key].datas.push(item)
558            }
559            return acc
560          }, {})
561          return Object.values(groupedData)
562        },
563        /** 根据重量和数量获取订单物流信息 */
564        async getShippingInfo() {
565          console.log('this.order_product', this.order_product);
566          // 整单包邮,调用getShippingList
567          const shipKeys = Object.keys(this.order_product)
568          if (shipKeys.length === 0) return
569          shipKeys.forEach(key => {
570            this.order_product[key].resultData = this.resetProduct(this.order_product[key].products)
571          })
572          const all_free_ship = shipKeys.find(key => {
573            // 包邮类型产品不需要请求物流信息
574            const products = this.order_product[key].products
575            // 是否包邮或是否是满减
576            let shipmentProduct = products.find(item => item.shipment_type === 1 || item.shipment_type === 2)
577            if (this.order_id) {
578              shipmentProduct = products.find(item => item.cart_product.reduction_id
579                && item.cart_product.reduction_price === 0)
580            }
581            return !!shipmentProduct
582          })
583          // 如果整单包邮,再调用一次物流计算,传所有产品参数
584          // if (all_free_ship) {
585          //   this.setReductionFreeShiping()
586          //   return
587          // }
588          // 满减支付类型
589          // 参数为所有物流产品
590          const promiseAll = []
591          const shipment_product = Object.values(this.order_product).flatMap(item => item.products).map(item => this.getShipingItem(item))
592          shipKeys.forEach(key => {
593            if (key === 'free') {
594              this.order_product[key].resultData.forEach(val => {
595                this.$set(val, 'logistics', [])
596              })
597            }
598            // 包邮类型产品不需要请求物流信息
599            if (key !== 'free' && this.order_product[key].resultData.length > 0) {
600              this.order_product[key].resultData.forEach(val => {
601                this.$set(val, 'logistics', [])
602                // const shipment_product = val.datas.map(item => this.getShipingItem(item))
603                // 处理各个计算类型的产品参数
604                this.shipment_params.product = shipment_product
605                const order_id = this.order_id || 0
606                this.shipment_params.shipment_id = val.shipment_ids || ''
607                this.shipment_params.order_id = order_id
608                if (key === 'quantity') this.shipment_params.price_method = 1
609                if (key === 'weight') this.shipment_params.price_method = 2
610                if (key === 'volume') this.shipment_params.price_method = 4
611                // 选中地址再计算物流
612                promiseAll.push(
613                  new Promise(async (resolve, reject) => {
614                    try {
615                      const data = await this.getShippingList(this.shipment_params)
616                      // this.$set(this.order_product[key], 'logistics', data)
617                      if (data.length) {
618                        const currentShipmentDetailId = this.is_buy_now ? val.datas[0].cart_product.shipment_detail_id : 0
619                        let currentIndex = 0
620                        if (currentShipmentDetailId) {
621                          currentIndex = data.findIndex(val => val.id === currentShipmentDetailId)
622                          currentIndex = currentIndex > 0 ? currentIndex : 0
623                        }
624                        data[currentIndex].is_select = true
625                      }
626                      // this.$set(val, 'logistics', data)
627                      val.logistics = data
628                      // this.getLeastShipping(key, val) // 默认勾选最小运费
629                      resolve('')
630                    } catch (error) {
631                      reject(error)
632                    }
633                  })
634                )
635              })
636            }
637          })
638          try {
639            await Promise.all(promiseAll)
640            this.calculateShippingCost2(this.order_product)
641          } catch (error) {
642            console.log('error', error);
643
644            const content = this.utilts.$t('The money-off campaign has expired.')
645            const modal = new Modal().init({
646              title: window.app.utilts.$t('Confirm'),
647              content,
648              submitText: window.app.utilts.$t('Go To cart'),
649              isHideCancel: true,
650              onSubmit: async () => {
651                modal.destroy()
652                const href = globalThis.Server.getRinseHref('/cart.html', window.app.info.site)
653                window.location.href = href
654              },
655              onCancel: async () => { modal.destroy() }
656            }).open()
657          }
658        },
659        /** 默认选取最小物流运费 */
660        getLeastShipping(key, val) {
661          if (this.order_product[key].resultData.length) {
662            if (val.logistics?.length) {
663              const cost = val.logistics.map(item => item.shipment_cost)
664              const minCost = Math.min.apply(null, cost)
665              let current = 0
666              cost.forEach((data, index) => { if (data === minCost) current = index });
667              this.changeLogistics(val.logistics[current], key, val.shipment_method_ids)
668            } else {
669              this.logistics_price = 0
670            }
671          }
672        },
673        /** 去支付 */
674        setPayPal(orderID) {
675          return new Promise((resolve, reject) => {
676            const visitor_code = this.order_detail.visitor_code || window.app.info.user.visitor_code
677            const addressId = this.order_address.id || 0
678            this.api.toPayPal(orderID, this.payment_id, this.payment_type, visitor_code, addressId)
679              .then(res => {
680                resolve(res)
681              })
682              .catch(err => {
683                this.utilts.setBtnLoadingStatus(this.placeOrder, false)
684                reject(err)
685              })
686          })
687        },
688        /**选择支付方式 */
689        changePayType(id, type = 0) {
690          if (this.isOrderDisable && type === 1) {
691            const tipStr = window.app.utilts.$t('Please fill in the delivery address before selecting the payment method')
692            const tipStr2 = window.app.utilts.$t('This Supplier/Shipping Company does not deliver to your selected Country/Region.')
693            let str = ''
694            // 如果未登录使用formData的国家判断提示
695            if (!window.app.info.user.is_login) str = this.formData.country_id ? tipStr2 : tipStr
696            // 登录使用订单地址国家判断提示
697            else {
698              if (!this.order_address) str = tipStr
699              else str = this.order_address.country_id ? tipStr2 : tipStr
700            }
701            new Message().error(this.utilts.$t(str))
702            return
703          }
704          this.payType.forEach(item => {
705            if (item.id === id) {
706              item.isChoose = true
707              this.payment_type = item.type
708              this.payment_id = id
709              this.is_credit_card = !!item.is_credit_card
710            }
711            else {
712              item.isChoose = false
713            }
714          })
715        },
716        /**支付方式列表 */
717        async getPayType() {
718          const list = await this.api.getPayType()
719          // 设置默认支付方式
720          let item = list.find(p => p.isChoose)
721          // 如果没有设置第一个为默认
722          if (!item) {
723            // 如果有支付方式使用第一个
724            if (list.length > 0) { item = list[0] }
725            if (item) item.isChoose = true
726          }
727          if (item) {
728            this.payment_type = item.type
729            this.payment_id = item.id
730            this.is_credit_card = !!item.is_credit_card
731          }
732          this.$set(this, 'payType', list)
733        },
734        /** 信用卡账单支付order_bill参数 */
735        setCreditCarBill() {
736          // 账单用默认地址
737          if (this.is_credit_card && this.is_same_address) {
738            const address = this.order_address
739            return {
740              first_name: address.first_name,
741              last_name: address.last_name,
742              phone: address.phone,
743              country_id: address.country_id,
744              province_id: address.province_id,
745              city: address.city,
746              address_one: address.address_one,
747              address_two: address.address_two,
748              zip_code: address.zip_code,
749              area_code: this.order_address.area_code,
750              email: address.email
751            }
752          }
753          // 账单用新的地址
754          else if (this.is_credit_card && !this.is_same_address) {
755            const credit = this.creditformData;
756            return {
757              first_name: credit.first_name,
758              last_name: credit.last_name,
759              phone: credit.phone,
760              country_id: credit.country_id,
761              province_id: credit.province_id,
762              city: credit.city,
763              address_one: credit.address_one,
764              address_two: this.order_address.address_two,
765              zip_code: credit.zip_code,
766              area_code: this.order_address.area_code,
767              email: credit.email
768            }
769          }
770          return null
771        },
772        /**
773         * 检查购物车产品信息完整性
774         * 0-正常;1-产品下架;2-款式不存在;3-价格变化;4-无库存;5-库存不足
775         */
776        checkoutCartProduct() {
777          // 有订单详情
778          const serial_num = this.order_detail.serial_number || this.serial_number
779          let coupon_id = 0
780          if (this.couponInfo) coupon_id = this.couponInfo.id || 0
781          const checkInfo = this.selected_pro.map(item => {
782            let selling_price = 0
783            let reduction_id = item.reduction_id
784            let discount_id = item.discount_id
785            const product = item.cart_product
786            const discount = product.discount
787            // 优惠券id
788            if (serial_num) {
789              coupon_id = product.coupon_member_id || 0
790              reduction_id = product.reduction_id || 0
791              discount_id = product.discount_id || 0
792            }
793            if (this.is_buy_together) selling_price = item.unit_price || 0
794            else if (item.is_discount) selling_price = item.cost_price
795            else if (discount) selling_price = discount.selling_price / 100
796            else selling_price = item.cost_price
797            return {
798              product_id: item.product_id,
799              price_id: item.price_id,
800              quantity: item.quantity,
801              selling_price: selling_price,
802              reduction_id, // 满减id
803              discount_id,// 限时折扣id
804              coupon_id, // 优惠券id
805            }
806          })
807          let params = this.globalConfig.stock_available ? '1,2,3,4,5,6' : '1,2,3,6'
808          // 如果待支付过来的,4-无库存;5-库存不足不用判断
809          if (serial_num) params = '1,2,3,6'
810          let match_price_ids = ''
811          let ids = this.matchProducts.map(el => el.price_id)
812          if (this.is_buy_together) {
813            match_price_ids = ids.join(',')
814          }
815          return this.utilts.checkoutAvailableHint(checkInfo, true, params, 0, match_price_ids)
816        },
817        /**
818         * 更新购物车价格
819         */
820        updateCartAllPrice() {
821          // 设置满减信息
822          this.setReductionList()
823          // 设置优惠券信息
824          this.setCouponInfo()
825          // 总原价
826          const allOriginalPrice = this.api.getTotaloriginalPrice(this.cart_list)
827          // 总折扣价
828          const allDiscountPrice = this.api.getTotalDiscountPrice(this.cart_list)
829          // 总价格
830          const allPrice = this.api.getTotalAllPrice(this.cart_list)
831          // 总未打折价格
832          const allNoneDiscountPrice = this.api.getTotalNoneDiscountPrice(this.cart_list)
833          // 总满减价格
834          let allReductionPrice = 0
835          this.reductionList.forEach(p => allReductionPrice += p.reductionTotal || 0)
836          this.$set(this, 'selected_original_price', allOriginalPrice || 0)
837          this.$set(this, 'selected_discount_price', allDiscountPrice || 0)
838          this.$set(this, 'selected_pro_price', allPrice || 0)
839          this.$set(this, 'selected_none_discount_price', allNoneDiscountPrice || 0)
840          this.$set(this, 'selected_reduction_price', allReductionPrice || 0)
841        },
842        checkHint(resData) {
843          let submitText = 'ok'
844          let isHideCancel = true
845          const status = resData.status
846          const isCart = this.step === 2
847          if (isCart && status !== -100) { // status===-100 超时不显示cancel
848            submitText = 'Go to Cart'
849            isHideCancel = false
850          }
851          const content = resData.list.map(p => {
852            const list = this.selected_pro.filter(item =>
853              Number(item.product_id) === Number(p.product_id) &&
854              Number(item.price_id) === Number(p.price_id))
855            const titleStr = list.map(p =>
856              `<div class="unit-cart__hint">${p.cart_product.product_title}<span>$${p.unit_price} * ${p.quantity}</span></div>`
857            ).join('')
858            return titleStr
859          })
860          let title = window.app.utilts.$t(resData.hintStr)
861          let text = content.join('')
862          if (!text) {
863            const defaultStr = 'The network cannot be connected, please make another payment'
864            text = window.app.utilts.$t(defaultStr)
865            title = window.app.utilts.$t('Reminder')
866          }
867          if (status === 6) {
868            text = window.app.utilts.$t(resData.hintStr)
869            title = window.app.utilts.$t('Reminder')
870          }
871          const modal = new Modal().init({
872            title: title,
873            content: text,
874            submitText: window.app.utilts.$t(submitText),
875            isHideCancel,
876            className: 'unit_cart__checkHint',
877            onSubmit: () => {
878              // 超时连接进,什么也不要做
879              if (isCart && status !== -100) {
880                window.location.href = globalThis.Server.getRinseHref('/cart.html', window.app.info.site)
881              } else if (status === 3 && status !== -100) {
882                window.location.reload()
883              }
884              modal.destroy()
885            },
886            onCancel: () => modal.destroy()
887          }).open()
888        },
889        setCountTime() {
890          this.cart_list
891            .filter(item => item.is_discount === 1)
892            .forEach(item => {
893              this.priceManager.discount.countDown(item, this)
894            })
895        },
896        /** 整单包邮物流计算 */
897        async setReductionFreeShiping() {
898          const shipment = {}
899          let shipment_product = []
900          shipment.country_id = this.shipment_params.country_id
901          shipment.province_id = this.shipment_params.province_id
902          Object.keys(this.order_product).forEach(key => {
903            this.order_product[key].resultData.forEach(val => {
904              this.$set(val, 'logistics', []) // 清空物流信息
905              const products = val.datas
906              let price_method = 0
907              if (key === 'quantity') price_method = 1
908              else if (key === 'weight') price_method = 2
909              const list = products.map(item => {
910                const shipItem = this.getShipingItem(item)
911                shipItem.price_method = price_method
912                return shipItem
913              })
914              shipment_product = [...shipment_product, ...list]
915            })
916          })
917          // 处理各个计算类型的产品参数
918          shipment.product = shipment_product
919          shipment.shipment_id = this.shipment_params.shipment_id
920          shipment.price_method = 0
921          const order_id = this.order_id || 0
922          shipment.order_id = order_id
923          const shipment_list = await this.getShippingList(shipment)
924          // 重新更新物流信息
925          Object.keys(this.order_product).forEach(key => {
926            this.order_product[key].resultData.forEach(val => {
927              val.datas.forEach(item => {
928                const method = item.cart_product.shipment_method
929                const shipment_ids = item.cart_product.shipment_ids ? item.cart_product.shipment_ids.split(',').map(val => val * 1) : ''
930                const shipList = shipment_list.filter(ship => ship.price_method === method && (shipment_ids.includes(ship.shipment_id) || shipment_ids === ''))
931                shipList.forEach(p => {
932                  // const logis = this.order_product[key].logistics
933                  const logis = JSON.parse(JSON.stringify(val.logistics))
934                  const info = logis.find(pp => pp.id === p.id)
935                  if (!info) { logis.push(p) }
936                  val.logistics = logis
937                })
938              })
939            })
940          })
941          Object.keys(this.order_product).forEach(key => {
942            this.order_product[key].resultData.forEach(val => {
943              // const logisticsList = val.logistics
944              // // 默认勾选最小运费
945              // logisticsList.forEach(() => { this.getLeastShipping(key, val) })
946              this.getLeastShipping(key, val)
947            })
948          })
949        },
950        /** 物流信息 */
951        getShipingItem(item) {
952          let weight = item.cart_product.weight || item.weight || 0
953          const quantity = item.quantity
954          const reduction_id = item.reduction_id || item.cart_product.reduction_id || 0
955          const product_id = item.cart_product.product_id || item.product_id || 0
956          const price_id = item.price_id || 0
957          const selling_price = item.cart_product.selling_price || 0
958          const discount_quantity = item.limit_buy || 0
959          if (this.globalConfig.weight_unit === 'g') weight = Number(weight / 1000)
960          return { price_id, selling_price, discount_quantity, quantity, weight, reduction_id, product_id }
961        },
962        checkWindowOpen(url, id) {
963          const site = window.app.info.site
964          const paymentType = this.utilts.getPaymentName(this.payment_type)
965          const aid = this.order_address.id || 0
966          const checkoutUrl = `/checkout.html?id=${id}&ad=${aid}&payment_type=${paymentType}`
967          const href = globalThis.Server.getRinseHref(checkoutUrl, site)
968          this.utilts.checkWindowOpen(url, () => {
969            window.location.href = href
970          })
971        },
972        // paypal 初始化
973        initPaypal() {
974          // 获取paypal client_id
975          const info = this.payType.find(p => p.type === 11)
976          let client_id = ''
977          if (info) client_id = info.params.client_id
978          if (!client_id) new Message().error(this.utilts.$t('paypal client id error'))
979          // 如果初始化了,就不再次初始化了
980          if (this.payPalSdk) return
981          this.payPalSdk = PaypalSdk.ins(client_id).init()
982          // 创建订单方法
983          this.payPalSdk.payOrder = () => {
984            return this.initCartSecondStep()
985          }
986          // 监听支付完成方法
987          this.payPalSdk.paypalCapture = () => this.paypalCapture()
988          // 支付完成删除购物车列表
989          this.payPalSdk.paypalDeleteCartList = () => this.deleteCartList()
990          // 订单合法性验证
991          this.payPalSdk.paypalCheckValid = async () => {
992            await this.initCheckoutConfig() //各种判断检查条件
993            return this.checkOrderpaid()
994          }
995        },
996        initAirwallex() {
997          // 获取paypal client_id
998          // 如果初始化了,就不再次初始化了
999          if (this.airwallexSdk) return
1000          this.airwallexSdk = AirwallexSdk.ins().init()
1001        },
1002        /** 信用卡form Post 提交表单 */
1003        _postcall(url, params, target, order_id = 0) {
1004          const currentOrderId = order_id
1005          const tempform = document.createElement("form")
1006          tempform.action = url
1007          tempform.method = "post"
1008          tempform.style.display = "none"
1009          for (var key in params) {
1010            var opt = document.createElement("input")
1011            opt.name = key
1012            opt.value = params[key]
1013            tempform.appendChild(opt)
1014          }
1015          var opt = document.createElement("input")
1016          opt.type = "submit"
1017          tempform.appendChild(opt)
1018          document.body.appendChild(tempform)
1019          // 内嵌形式
1020          if (target) {
1021            const iframe_box_wrap = document.createElement('div')
1022            iframe_box_wrap.classList="iframe_pay_box_wrap"
1023            iframe_box_wrap.innerHTML = `
1024            <div class="iframe_pay_box">
1025              <iframe width="100%" height="100%" scrolling="auto" name="ifrm_creditcard_checkout" id="ifrm_creditcard_checkout" style="border:none; margin: 0 auto; overflow:auto;"></iframe>
1026            </div>
1027            <div id="iframe_preloader_wrap">
1028              <div id="iframe_preloader">
1029                <span></span>
1030                <span></span>
1031                <span></span>
1032                <span></span>
1033              </div>
1034            </div>
1035            `
1036            document.body.appendChild(iframe_box_wrap)
1037            tempform.target = target
1038            const param = window.location.search ? '&pay_type=oceanPay' : '?pay_type=oceanPay'
1039            // 访客记录下点击了前海弹窗
1040            const iframe = iframe_box_wrap.querySelector('iframe')
1041            const loadAfter = ()=> {
1042              window.app.info.utilts.postVisitor(param)
1043              iframe_box_wrap.classList.add('show_iframe_page')
1044            }
1045            if (iframe.attachEvent) {
1046              iframe.attachEvent("onload", loadAfter)
1047            } else {
1048              iframe.onload = loadAfter
1049            }
1050
1051            // 非苹果内核时回退弹窗
1052            if(!(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))) {
1053
1054              // 返回上一记录执行方法
1055              const cancelFun = () => {
1056                const s = window.location.search
1057                if (window.location.pathname.startsWith('/cart') && s && s.indexOf('&ad=') === -1) {
1058                  let newSearch = s + '&ad=' + this.order_address.id
1059                  if (newSearch.includes('isBuy=1')) newSearch = newSearch.replace('isBuy=1','cancelBuy=1')
1060                  if (s.indexOf('&id=') === -1 && s.indexOf('?id=') === -1) {
1061                    const id = this.order_id || currentOrderId
1062                    if (id) newSearch += '&id=' + id
1063                  }
1064                  window.history.replaceState(null, "", newSearch)
1065                }
1066                window.location.reload()
1067              }
1068
1069              window.history.pushState({title:'上一页'}, 'title', '')
1070              window.history.pushState({title:'当前'}, 'title', '')
1071              window.removeEventListener('popstate', _that.popstateInit)
1072              window.addEventListener('popstate', () => {
1073                if (!window.history.state) {
1074                  cancelFun()
1075                } else {
1076                  if (window.history.state.title === '上一页') {
1077                    if (confirm('Would you like to cancel the order?') === true) {
1078                      const s = window.location.search
1079                      const param = s ? '&payment_back_status=cancel' : '?payment_back_status=cancel'
1080                      window.app.info.utilts.postVisitor(param)
1081                      if(s.includes('buy_source=cart') && s.indexOf('id=') === -1) cancelFun()
1082                      else {
1083                        history.back()
1084                        // 如果退回来有state则刷新
1085                        if (window.history.state) cancelFun()
1086                      }
1087                    } else {
1088                      history.forward()
1089                    }
1090                  } else if (window.history.state.title !== '当前') {
1091                    window.location.reload()
1092                  }
1093                }
1094
1095              }, false)
1096
1097            }
1098
1099          }
1100          tempform.submit()
1101          document.body.removeChild(tempform)
1102        }
1103      }
1104    })
1105  }
1106}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.