PageSourceSearch

https://www.linyangpvc.com/assets/js/unit/cart-checkout.js

js linyangpvc.com collected 2026-10-04 04:55:03 UTC 18,268 bytes, 457 lines download raw bytes

1class ScriptCartCheckout extends Script {
2  constructor(params) {
3    super(params)
4    this.utils = Utilts.ins()
5  }
6  /** 初始化,支持异步 */
7  async init() {
8    const _this = this
9    await new Load('/assets/plugins/vue.min.js')
10    await new Load('/assets/plugins/selector.js')
11    await new Load('/assets/plugins/country.js')
12    new Vue({
13      el: `#${this.attrId} .unit-cart-checkout__app`,
14      mixins: [this._UnitMixinsData()],
15      created() {
16        this.isBuyTogether = _this.utilts.getQuery('isBuyTogether') || 0
17        let matchProducts = []
18        if (this.isBuyTogether) {
19          // 如果是搭配产品,必须加上搭配价格
20          matchProducts = JSON.parse(sessionStorage.getItem('matchProducts') || '[]')
21          this.matchProducts = matchProducts
22        }
23        window.payinfo = { currency_code: 'USD' }
24        this.init()
25      },
26      methods: {
27        async init() {
28          await this.visitorCheckout()
29          await this.initOrderDetail()
30          await this.getPayType()
31          this.getCountryList()
32        },
33        /**获取当前订单产品详情 */
34        async initOrderDetail() {
35          const orderId = Number(_this.utils.getQuery('id')) || 0
36          this.addressId = _this.utilts.getQuery('ad') || 0
37          const params = {
38            site_id: window.app.info.site.site_id,
39            id: orderId,
40            visitor_code: window.app.info.getOrderVisitorCode(orderId) || window.app.info.getVisitorCode()
41          }
42          const data = await this.api.getOrderDetail(params, this.multiple_address, this.isBuyTogether, this.matchProducts)
43          this.payment_id = data.payment_id
44          this.$set(this, 'order_detail', data)
45        },
46        /**获取国家列表 */
47        async getCountryList() {
48          const data = await this.api.getCountryList()
49          this.$set(this, 'multiple_address', data)
50          this.initCountrySelect()
51        },
52        // 国家下拉插件
53        initCountrySelect() {
54          const $country = this.$refs.country
55          if (!$country) return
56          const option = this.multiple_address.map(item => {
57            return { name: item.en_name, value: item.id }
58          })
59          this.pluginsCountry = new PluginSelector({
60            target: $country, option, require: true, placeholder: window.app.utilts.$t('Country') + '/' + window.app.utilts.$t('Region'), confirmTip: window.app.utilts.$t('the content can not be blank'), onChange: res => {
61              this.$set(this.formData, 'country_id', res.value)
62              this.$set(this.formData, 'country_name', res.name)
63            }
64          })
65          this.pluginsCountry.init()
66          // 手机端初始化
67          if (window.innerWidth < 768) this.initMobileCountrySelect()
68        },
69        // 初始化手机端国家
70        async initMobileCountrySelect() {
71          // 清除下拉插件事件
72          this.pluginsCountry.clearInput()
73          const $input = this.pluginsCountry.$input
74          const close = (p) => {
75            this.pluginsCountry.setValue(p.id)
76            this.$set(this.formData, 'country_id', p.id)
77            this.$set(this.formData, 'country_name', p.en_name)
78            modal.close()
79          }
80          // 国家弹窗内容初始化
81          if (!this.ModalCountry) this.ModalCountry = await new PluginCountry({ onClose: close }).init()
82          const modal = new Modal()
83          modal.init({
84            body: this.ModalCountry.$target,
85            title: window.app.utilts.$t('Select Country/region'),
86            size: 'lg',
87            className: 'country-modal',
88            isHideCancel: true,
89            submitText: window.app.utilts.$t('Cancel')
90          })
91          $input.addEventListener('click', () => {
92            modal.open()
93            this.ModalCountry.initScroll()
94          })
95        },
96        /**支付列表 */
97        getPayType() {
98          return new Promise((resolve, reject) => {
99            const order = this.order_detail
100            this.api.getPayType().then(res => {
101              res.forEach(item => {
102                if (item.id === order.payment_id) this.$set(this, 'payType', item)
103                // 西联
104                if (item.type === 12) this.$set(this, 'payment_form_info', item.params)
105              })
106              resolve()
107            }).catch(err => reject(err))
108          })
109        },
110        /**删除当前地址 */
111        delThisAddress(index) {
112          this.addressList.splice(index, 1)
113        },
114        /**西联支付 */
115        toWesternPay(orderId) {
116          const $form = document.querySelector('.western-form')
117          $form.addEventListener('submit', (e) => { e.preventDefault() })
118          $form.classList.add('was-validated')
119          if ($form.checkValidity() === false) return
120          this.request_success = true
121          const visitor_code = this.order_detail.visitor_code || window.app.info.user.visitor_code
122          this.api.toPay({
123            visitor_code, orderID: Number(orderId), payment_id: this.payment_id,
124            payCode: 12, formData: this.formData, addressId: this.addressId
125          })
126            .then(_res => {
127              const paymentType = window.app.utilts.getPaymentName(this.payType.type)
128              const url = `/complete.html?id=${orderId}&payment_type=${paymentType}&payment_status=success`
129              const href = globalThis.Server.getRinseHref(url, window.app.info.site)
130              window.location.href = globalThis.Server.getRinseHref(`${location.origin}${href}`, window.app.info.site)
131            })
132        },
133        /** paypal支付, 信用卡支付 */
134        toPayPal(orderId, event) {
135          const visitor_code = this.order_detail.visitor_code || window.app.info.user.visitor_code
136          this.request_success = true
137          this.api.toPay({
138            visitor_code, orderID: Number(orderId), payment_id: this.payment_id,
139            payCode: this.payType.type, formData: {},
140            addressId: this.addressId
141          })
142            .then(res => {
143              if (res.data.link) {
144                const site = window.app.info.site
145                const url = globalThis.Server.getRinseHref(res.data.link, site)
146                window.app.utilts.checkWindowOpen(url)
147              }
148              window.app.utilts.setBtnLoadingStatus(event.target, false)
149            }).catch(err => {
150              window.app.utilts.setBtnLoadingStatus(event.target, false)
151            })
152        },
153        operationTips(val) {
154          this.friendly_reminder = true
155          this.friendly_reminder_info = val
156          setTimeout(() => {
157            this.friendly_reminder = false
158          }, 1000);
159        },
160        /** 判断游客状态 */
161        visitorCheckout() {
162          this.api.visitorCheckout()
163        },
164        /** 检测paypal是否支付成功 */
165        initPaypal() {
166          let $modal = document.querySelector($event.target.dataset.target)
167          if ($modal) this.api.modalShowOrHide($modal)
168        },
169        /** 监测是否支付 */
170        async checkOrderStatus(event) {
171          window.app.utilts.setBtnLoadingStatus(event.target, true)
172          await this.initOrderDetail()
173          if (this.order_detail.status === 1) {
174            if (!this.isPayFail) {
175              this.isPayFail = true
176              window.app.utilts.setBtnLoadingStatus(event.target, false)
177            } else {
178              this.isPayFail = false
179              // 网站埋点事件
180              this.setCheckOutTage('click_to_continue')
181              this.toPayPal(this.order_detail.id, event)
182            }
183          } else if (this.order_detail.status === 31) {
184            new Message().error('The order has been cancelled')
185            setTimeout(() => {
186              const href = globalThis.Server.getRinseHref(`/`, window.app.info.site)
187              window.location.href = href
188            }, 1000);
189          } else {
190            const paymentType = window.app.utilts.getPaymentName(this.payType.type)
191            const href = `/complete.html?id=${this.order_detail.id}&payment_type=${paymentType}&payment_status=success`
192            window.location.href = globalThis.Server.getRinseHref(`${location.origin}${href}`, window.app.info.site)
193          }
194        },
195        /** 关闭信息弹窗 */
196        async closeOrderPay(event) {
197          window.app.utilts.setBtnLoadingStatus(event.target, true)
198          await this.initOrderDetail()
199          this.setCheckOutTage('commodity_payment_cancel')
200          // 取消回到支付页
201          if (this.order_detail.status === 1) {
202            const url = `/cart.html?id=${this.order_detail.id}&ad=${this.addressId}`
203            window.location.href = globalThis.Server.getRinseHref(`${location.origin}${url}`, window.app.info.site)
204          } else if (this.order_detail.status === 31) {
205            // 订单取消时回到首页
206            new Message().error('The order has been cancelled')
207            setTimeout(() => {
208              const href = globalThis.Server.getRinseHref(`/`, window.app.info.site)
209              window.location.href = href
210            }, 1000);
211          } else if (this.order_detail.status === 31) {
212            // 支付成功回到支付完成页
213            const paymentType = window.app.utilts.getPaymentName(this.payType.type)
214            const url2 = `/complete.html?id=${this.order_detail.id}&payment_type=${paymentType}&payment_status=success`
215            window.location.href = globalThis.Server.getRinseHref(`${location.origin}${url2}`, window.app.info.site)
216          } else if (this.order_detail.status === 4) {
217            // 其它取消回到首页
218            const href = globalThis.Server.getRinseHref(`/`, window.app.info.site)
219            window.location.href = href
220          } else {
221            window.app.utilts.setBtnLoadingStatus(event.target, false)
222          }
223        },
224        toHomePage() {
225          this.setCheckOutTage('payment_back_to_homepage')
226          const href = globalThis.Server.getRinseHref(`/`, window.app.info.site)
227          window.location.href = href
228        },
229        setCheckOutTage(eventName) {
230          // 网站埋点事件
231          const type = this.payType.type
232          const gtagInfo = {
233            payment_type: window.app.utilts.getPaymentName(type),
234            order_id: this.order_detail.serial_number
235          }
236          window.app.utilts.setGtag(eventName, gtagInfo)
237        }
238      }
239    })
240  }
241  /** 基本信息 */
242  _UnitMixinsData() {
243    return {
244      data: {
245        api: ScriptCartCheckoutApi.ins(),
246        multiple_address: [],
247        province_id: 0,
248        province: [],
249        order_address: {},
250        logisticsList: [],
251        logistics_price: 0,
252        payment_id: 0,
253        payList: [],
254        payType: {},
255        order_product: [],
256        order_info: {},
257        order_status: true,
258        order_detail: {},
259        friendly_reminder: false,
260        friendly_reminder_info: "",
261        request_success: false,
262        payment_form_info: {},
263        pluginsCountry: null,
264        ModalCountry: null,
265        form_rule: {
266          mtcn: '^[\\d]{10}$',
267          payment_amount: '^[\\d\\.]+$',
268          name: '^[a-zA-Z]{1,20}$'
269        },
270        formData: {
271          first_name: '',
272          last_name: '',
273          mtcn: '',
274          country_id: '',
275          country_name: '',
276          currency_code: 'USD',
277          payment_amount: '',
278          content: ''
279        },
280        isPayFail: false,
281        payTimes: 0,
282        addressId: 0,
283        is_buy_together: 0, // 是否一起购买
284        matchProducts: []
285      }
286    }
287  }
288}
289
290class ScriptCartCheckoutApi {
291  constructor() {
292
293  }
294  /** 单例模式 */
295  static ins() {
296    if (!this.instance) {
297      return this.instance = new ScriptCartCheckoutApi()
298    }
299    return this.instance
300  }
301  getOrderDetail(params, multiple_address, isBuyTogether=0, matchProducts=[]) {
302    return new Promise((resolve, reject) => {
303      Utilts.ins().request({ url: '/order/detail', method: 'GET', params })
304        .then(res => {
305          let data = res.data
306          data.order_product = data.order_product || []
307          data.total_amount = (data.total_amount / 100).toFixed(2)
308          data.shipping_price = (data.shipping_price / 100).toFixed(2)
309          data.product_price = (data.product_price / 100).toFixed(2)
310          data.total_number = 0
311          data.order_product = data.order_product.map(item => {
312            item.cost_price = item.cost_price / 100
313            item.selling_price = (item.selling_price / 100).toFixed(2)
314            item.total_price = (parseFloat(item.selling_price) * parseFloat(item.quantity)).toFixed(2)
315            data.total_number += item.quantity
316            // item.product_attr_detail = item.product_attr_detail.map(pro => {
317            //   return { title: pro.title, content: pro.content }
318            // })
319            item.thumb_prefix = item.thumb_prefix || item.product_thumb
320            return item
321          })
322          const info = multiple_address.find(item => Number(item.id) === data.order_shipment[0].country_id)
323          if (info) {
324            data.order_shipment[0].country_en_name = info.en_name
325            const province = info.province.find(province => province.id === data.order_shipment[0].province_id)
326            if (province) {
327              data.order_shipment[0].province_en_name = province.en_name
328            }
329          }
330          resolve(data)
331        })
332    })
333  }
334  getCountryList() {
335    return new Promise((resolve, reject) => {
336      window.app.info.getCountryList().then(res => resolve(res))
337    })
338  }
339  /** 获取支付方式 */
340  getPayType() {
341    const params = { site_id: window.app.info.site.site_id, scene: 2 }
342    return new Promise((resolve, reject) => {
343      Utilts.ins().request({ url: '/payment-config/get-list-by-site', prefix: 'qqt', method: 'GET', params })
344        .then(res => {
345          if (res.code === 0) {
346            const data = res.data.filter(item => {
347              // paypal
348              if (item.type === 11) {
349                item.img = '/assets/images/Paypal.svg'
350                item.name = Utilts.ins().$t('Paypal')
351              } else if (item.type === 12) { // 西联
352                item.img = '/assets/images/westernunion.svg'
353                item.name = Utilts.ins().$t('Western Union')
354              } else if ([13, 14, 15, 17, 18, 19].includes(item.type)) {
355                item.img = '/assets/images/creditCard.png'
356                item.name = Utilts.ins().$t('Credit or Debit Cards')
357              }
358              item.isChoose = false
359              return item.status
360            })
361            resolve(data)
362          } else reject(res)
363        }).catch(err => reject(err))
364    })
365  }
366  toPay(params) {
367    const { visitor_code, orderID, payment_id, payCode, addressId } = params
368    let formData = params.formData || {}
369    const paymentType = window.app.utilts.getPaymentName(this.payType)
370    const completeUrl = globalThis.Server.getRinseHref('/complete.html', window.app.info.site)
371    let cancel_url = `${location.origin}${completeUrl}`
372    if (payCode === 13 || payCode === 17) {
373      const cartUrl = globalThis.Server.getRinseHref(`/cart.html?id=${orderID}&ad=${addressId}`, window.app.info.site)
374      cancel_url = `${location.origin}${cartUrl}`
375    }
376    const return_url = `${location.origin}${completeUrl}?id=${orderID}&payment_type=${paymentType}`
377    if(payCode==13){
378      formData.java_enabled = window.navigator.javaEnabled()
379      formData.language = window.navigator.language
380      formData.screen_height = window.screen.height
381      formData.screen_width = window.screen.width
382      formData.time_zone_offset = new Date().getTimezoneOffset()
383    }
384    return new Promise((resolve, reject) => {
385      Utilts.ins().request({
386        url: '/order/order-paid',
387        prefix: 'jmc',
388        method: 'POST',
389        params: {
390          order_id: orderID,
391          scene: 2,
392          payment_id: payment_id,
393          payment_type: payCode,
394          visitor_code,
395          return_url,
396          cancel_url,
397          ...formData
398        }
399      }).then(res => {
400        resolve(res)
401      }).catch(err => {
402        const msg = 'The network cannot be connected, please make another payment'
403        new Message().error(err.msg || msg)
404        reject(err)
405      })
406    })
407  }
408  visitorCheckout() {
409    if (window.app.info.user.is_login) return
410    Utilts.ins().checkoutConfig().then(res => {
411      if (!res.visitor_checkout) {
412        new Message().warn('Please login in first')
413        window.location.href = globalThis.Server.getRinseHref('/login.html', window.app.info.site)
414      }
415    })
416  }
417  /**弹窗交互 */
418  modalShowOrHide(el) {
419    let $dom = el
420    // 绑定关闭事件
421    let closeBtn = $dom.querySelectorAll('[data-dismiss="modal"]')
422    for (const el of closeBtn) {
423      el.onclick = () => _changeModal()
424    }
425    // 窗口显示隐藏
426    _changeModal()
427    function _changeModal() {
428      // 删除动画,因为会引起弹窗的效果
429      const $card = document.querySelector('[package-type="cart"]')
430      if ($card) {
431        $card.classList.remove('animate')
432        $card.classList.remove('animate__animated')
433        $card.classList.remove('animate__fadeInUp')
434      }
435      if (Utilts.ins().hasClass($dom, 'show')) {
436        // 隐藏弹窗
437        // 删除z-index因为sticky 导致挡住弹出框问题
438        $dom.classList.remove('show')
439        $dom.style.display = 'none'
440        document.querySelector('.modal-backdrop').classList.remove('show')
441        Utilts.ins().removeNode(document.querySelector('.modal-backdrop'))
442        document.body.classList.remove('modal-open')
443      } else {
444        // 打开弹窗
445        // 添加z-index因为sticky 导致挡住弹出框问题
446        $dom.classList.add('show')
447        $dom.style.display = 'block'
448        if (!document.querySelector('.modal-backdrop')) {
449          Utilts.ins().createDom(document.querySelector('#checkoutModal'), 'div', ['modal-backdrop', 'fade', 'show'])
450        } else {
451          document.querySelector('.modal-backdrop').classList.add('show')
452        }
453        document.body.classList.add('modal-open')
454      }
455    }
456  }
457}

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.