PageSourceSearch

https://www.hanbi-hotelsupplies.com/assets/js/unit/detail-price.js

js hanbi-hotelsupplies.com collected 2026-10-08 16:22:02 UTC 20,572 bytes, 491 lines download raw bytes

1class ScriptDetailPrice extends Script {
2  constructor(params) {
3    super(params)
4    this.$unit = document.getElementById(`${this.attrId}`)
5    if (this.$unit === null) return;
6    /** unit-detail-price */
7    this.U = (suffix, isSelector = true) => `${isSelector ? '.' : ''}unit-detail-price${suffix}`
8    // 更多优惠信息按钮
9    this.$detail = this.$unit.querySelector(this.U('--detail'))
10    // 折扣更多列表项
11    this.$discountList = this.$unit.querySelector(this.U('--discount-list'))
12    // 倒计时,时,分秒
13    this.$date = this.$unit.querySelector(this.U(`--date`))
14    this.$discountTimer = this.$unit.querySelector('.discount-timer')
15    this.$dd = this.$unit.querySelector(this.U('--date_limt--dd'))
16    this.$hh = this.$unit.querySelector(this.U('--date_limt--hh'))
17    this.$mm = this.$unit.querySelector(this.U('--date_limt--mm'))
18    this.$ss = this.$unit.querySelector(this.U('--date_limt--ss'))
19
20    this.$modal = this.$unit.querySelector(this.U('__model'))
21    this.$modalContent = this.$modal.querySelector(this.U('__model_content'))
22    this.$coupon = this.$unit.querySelector(this.U('_box--list'))
23
24    this.counpList = []
25    this.isMoreCoupon = false
26
27    // 查找原价信息元素
28    this.$price = this.$unit.querySelector(this.U('--prices_sell-price'))
29    this.$cost = this.$unit.querySelector(this.U('--prices_cost-price'))
30    this.$newPrice = this.$price.querySelector(this.U('--prices_sell-price_new'))
31    this.$newCostPrice = this.$cost.querySelector(this.U('--prices_cost-price_new'))
32
33    //满减信息
34    this.$reduce = this.$unit.querySelector(this.U('__reduce'))
35    this.$off = this.$unit.querySelector(this.U('--prices__off'))
36    this.$costPriceMin = this.$cost.querySelector(this.U('--price_cost-price_original--min'))
37    this.$costPriceMax = this.$cost.querySelector(this.U('--price_cost-price_original--max'))
38    this.$originalPrice = this.$price.querySelector(this.U('--prices_sell-price_original'))
39  }
40  async init() {
41    // await new Load('/assets/plugins/couponSvg.js')
42    // 初始化更多detail展开事件
43    this.initDetailEvent()
44    this.initAllCounponList()
45  }
46  /** 初始化显示折扣信息 */
47  initDicountInfo() {
48    const detail = window.app.info.productDetail
49    // 显示满减信息
50    this.showReduce(detail)
51    // 如果有不是限时折扣显示原价
52    if (!detail.is_discount) {
53      this.showOriginalPrice(detail)
54    } else {
55      this.showDiscountPrice(detail)
56    }
57  }
58  /**
59   * 显示原价
60   * @param {产品详情} detail 
61   * @returns 
62   */
63  showOriginalPrice(detail) {
64    // 隐藏折扣价信息
65    this.$newPrice.innerHTML = ''
66    this.$newCostPrice.innerHTML = ''
67    this.$off.classList.add('d-none')
68    this.$date.classList.add('d-none')
69    // ä»·æ ¼
70    const $originalPriceSymbol = this.$unit.querySelector(this.U('--prices_sell--i'))
71    const $originalPriceMin = this.$price.querySelector(this.U('--price_sell-price_original--min'))
72    const $originalPriceMax = this.$price.querySelector(this.U('--price_sell-price_original--max'))
73    if (this.$originalPrice) this.$originalPrice.classList.remove('d-none')
74    if ($originalPriceMin) {
75      $originalPriceMin.innerHTML = ''
76      if (detail.min_price <= 0) {
77        this.$unit.querySelector(this.U('__box-time')).classList.add('d-none')
78        $originalPriceSymbol.classList.add('d-none')
79        //this.$originalPrice.innerHTML = window.app.utilts.$t('No Quotation')
80      }
81      else {
82        this.$unit.querySelector(this.U('__box-time')).classList.remove('d-none')
83        $originalPriceSymbol.classList.remove('d-none')
84        $originalPriceMin.innerHTML = `${detail.min_price}`
85        window.app.info.productDetail.mainPrice = detail.min_price // 设置主产品价格,用于搭配产品计算价格
86        window.app.info.productDetail.mainOriginalPrice = detail.min_cost_price // 设置主产品价格,用于搭配产品计算价格
87        let matchProductsTotal = window.app.info.productDetail.matchProductsTotal || 0
88        // 如果有搭配产品,计算总价
89        let matchTotal = document.querySelector(`#${this.attrId} .pm-total-price`)
90        if (matchTotal) {
91          matchTotal.innerHTML = `$${(detail.min_price + matchProductsTotal).toFixed(2)}`
92        }
93
94        let matchProductsOriginalTotal = window.app.info.productDetail.matchProductsOriginalTotal || 0
95        // 如果有搭配产品,计算总价
96        let matchOriginalTotal = document.querySelector(`#${this.attrId} .pm-original-total-price`)
97        if (matchOriginalTotal) {
98          matchOriginalTotal.innerHTML = `$${(detail.min_cost_price + matchProductsOriginalTotal).toFixed(2)}`
99        }
100      }
101    }
102    const isShowMaxPrice = detail.max_price !== 0 && detail.min_price !== detail.max_price
103    if (isShowMaxPrice && $originalPriceMax) $originalPriceMax.innerHTML = `~ ${detail.max_price}`
104    else if ($originalPriceMax) $originalPriceMax.classList.add('d-none')
105    // 销售价格
106    const $costPrice = this.$cost.querySelector(this.U('--prices_cost-price_original'))
107    if ($costPrice) $costPrice.classList.remove('d-none')
108    // 为0不显示
109    if (detail.min_price <= 0) this.$costPriceMin.innerHTML = ''
110    else if (detail.min_cost_price <= 0)this.$costPriceMin.innerHTML = ''
111    else this.$costPriceMin.innerHTML = `$${detail.min_cost_price}`
112    const isShowMaxCostPrice = detail.max_cost_price !== 0 && detail.min_cost_price !== detail.max_cost_price
113    if (isShowMaxCostPrice && this.$costPriceMax) this.$costPriceMax.innerHTML = `~ ${detail.max_cost_price}`
114    else this.$costPriceMax.classList.add('d-none')
115    if(detail.min_cost_price <= 0){
116      this.$costPriceMax.innerHTML =`$${detail.max_cost_price}`
117    }
118  }
119  /**
120   * 显示折扣价格,分为默认显示,和选择款式以后的显示
121   * @param {产品详情} detail 
122   * @returns 
123   */
124  showDiscountPrice(detail) {
125    // 隐藏原价信息
126    this.$costPriceMin.innerHTML = ''
127    this.$costPriceMax.classList.add('d-none')
128    this.$originalPrice.classList.add('d-none')
129    this.$unit.querySelector(this.U('__box-time')).classList.remove('d-none')
130    const $originalPriceSymbol = this.$unit.querySelector(this.U('--prices_sell--i'))
131    // 显示价格为折扣的价格
132    this.$newPrice.innerHTML = ''
133    if (detail.is_pattern) { //如果款式区配显示匹配价格
134      if (detail.discount_price <= 0) {
135        // this.$newPrice.innerHTML = window.app.utilts.$t('No Quotation')
136        $originalPriceSymbol.classList.add('d-none')
137      } else {
138        $originalPriceSymbol.classList.remove('d-none')
139        this.$newPrice.innerHTML = `${detail.discount_price}`
140      }
141    }
142    else if (!detail.is_pattern) {
143      console.log(detail,'detaildetail')
144      if (detail.discount_min_price < 0) {
145        // this.$newPrice.innerHTML = window.app.utilts.$t('No Quotation')
146        $originalPriceSymbol.classList.add('d-none')
147      } else{
148        $originalPriceSymbol.classList.remove('d-none')
149        //款式不匹配有最大最小显示价格区间
150        var new_price = `${detail.max_price||detail.discount_price||detail.discount_max_price}`
151        this.$newPrice.innerHTML = `${detail.min_price}~${new_price}`
152        if (detail.min_price == new_price) {
153          //款式不匹配有最大最小显示价格区间
154          this.$newPrice.innerHTML = `${detail.min_price}`
155        } 
156      }
157      // else if (detail.discount_min_price !== detail.discount_max_price) {
158      //   $originalPriceSymbol.classList.remove('d-none')
159      //   //款式不匹配有最大最小显示价格区间
160      //   this.$newPrice.innerHTML = `${detail.discount_min_price}~${detail.discount_max_price}`
161      // } 
162      // else {
163      //   $originalPriceSymbol.classList.remove('d-none')
164      //   this.$newPrice.innerHTML = `${detail.discount_min_price}`
165      // }
166    }
167
168    // 显示的销售价格为折扣前的价格
169    this.$newCostPrice.innerHTML = ''
170    if (detail.is_pattern) { //如果款式区配显示匹配价格
171      if (detail.discount_price <= 0) this.$newCostPrice.innerHTML = ''
172      else this.$newCostPrice.innerHTML = `$${detail.discount_original_price}`
173    } else {
174      if (detail.discount_sell_min_price <= 0) this.$newCostPrice.innerHTML = ''
175      else if (detail.discount_sell_min_price !== detail.discount_sell_max_price) {
176        //款式不匹配有最大最小显示价格区间
177        this.$newCostPrice.innerHTML = `$${detail.min_price}~${detail.discount_sell_max_price}`
178      } else if (detail.discount_min_price !== 0) {
179        this.$newCostPrice.innerHTML = `$${detail.discount_sell_min_price}`
180      }
181    }
182    // 设置显示降价的比率
183    this.$off.classList.remove('d-none')
184    const $offRate = this.$off.querySelector(this.U('--prices_dis'))
185    $offRate.textContent = ''
186    if (detail.is_pattern) {
187      $offRate.textContent = `${detail.off_rate}% ` + window.app.utilts.$t('Off')
188    } else {
189      if (detail.off_rate > 0) {
190        $offRate.textContent = `${detail.off_rate}% ` + window.app.utilts.$t('Off')
191        this.$off.classList.remove('d-none')
192      }
193      else if (detail.min_off_rate !== detail.off_rate) {
194        $offRate.textContent = `${detail.min_off_rate}~${detail.off_rate}% ` + window.app.utilts.$t('Off')
195      }
196    }
197    // 倒计时
198    if (window.innerWidth < 768) {
199      const parent = document.querySelector('.unit-detail_content')
200      if (parent) parent.prepend(this.$date)
201    }
202    this.countTime()
203  }
204
205  /** 显示满减信息 */
206  showReduce(detail) {
207    const $reduceList = this.$reduce.querySelector(this.U('__reduce--list'))
208    const $show = this.$reduce.querySelector(this.U('__reduce--show'))
209    if ($reduceList === null || !detail.reduction || $reduceList.childNodes.length > 0) return
210    this.$reduce.classList.remove('d-none')
211    $reduceList.innerHTML = ''
212    detail.reduction.split(';').forEach((item, index) => {
213      const $el = document.createElement('div')
214      $el.classList.add('unit-detail-price__reduce--item')
215      if (index === 0 || window.innerWidth > 768) $el.classList.add('show')
216      $el.innerHTML = `<span class="unit-detail-price__reduce--txt">${item}</span>`
217      $reduceList.appendChild($el)
218    })
219    $reduceList.title = detail.reduction
220    const $reduceLink = this.$reduce.querySelector(this.U('__reduce--a'))
221    if ($reduceLink === null) return
222    $reduceLink.onclick = () => {
223      window.location.href = globalThis.Server.getRinseHref(`/reduction_detail/${detail.reduction_id}.html`, window.app.info.site)
224    }
225    // 展开符
226    $show.onclick = () => {
227      this.showReduceModal(detail)
228    }
229  }
230  showReduceModal(params) {
231    const $frage = document.createDocumentFragment()
232    const $div = document.createElement('div')
233    $div.classList.add('unit-detail-price__reduce--list')
234    params.reduction.split(';').forEach(data => {
235      const $el = document.createElement('div')
236      $el.classList.add('unit-detail-price__reduce--item', 'show')
237      $el.innerHTML = `<div class="unit-detail-price__reduce--txt">${data}</div>`
238      $div.appendChild($el)
239    })
240    $frage.appendChild($div)
241    const modal = new Modal()
242    modal.init({
243      title: window.app.utilts.$t('Offers and Discounts'),
244      body: $frage,
245      isHideCancel: true,
246      className: 'reduce-modal',
247      submitText: window.app.utilts.$t('Shop now'),
248      onSubmit: () => location.href = globalThis.Server.getRinseHref(`/reduction_detail/${params.reduction_id}.html`, window.app.info.site),
249      onCancel: () => modal.destroy()
250    }).open()
251  }
252  /**
253   * 根据产品信息显示倒计时 
254   * @param {产品信息} product 
255   */
256  countTime() {
257    // 如果有倒计时,处理显示倒计时
258    if (window.app.info.productDetail.is_discount) {
259      if (this.$date) this.$date.classList.remove('d-none')
260      const time = window.app.info.productDetail.count_time
261      this.utilts.countTime(this.utilts.getTimeParseInt(time), this.$discountTimer,
262        window.app.info.productDetail.detail_type, () => {
263          // 如果是正在进行的活动,价格恢复正常
264          if (window.app.info.productDetail.detail_type === 'now') {
265            setTimeout(() => {
266              this.countTimeFinish()
267            }, 1000);
268          } else if (window.app.info.productDetail.detail_type === 'upcoming') {
269            // 如果是即将进行的活动,继续倒计时为正在进行的活动
270            this.countTime()
271          }
272        })
273    }
274  }
275  /** 初始化更多detail展开事件 */
276  initDetailEvent() {
277    //如果没有detail 退出
278    if (!this.$detail) return;
279    const $detailIcon = this.$unit.querySelector(this.U('--detail_icon'))
280    this.$detail.addEventListener('click', () => {
281      if (!this.isMoreCoupon) {
282        $detailIcon.classList.add('rotate-icon')
283        this.setCouponList(this.counpList)
284        this.isMoreCoupon = true
285      } else {
286        $detailIcon.classList.remove('rotate-icon')
287        this.renderCouponList()
288        this.isMoreCoupon = false
289      }
290    })
291  }
292  /** 倒计时结束时,处理相关信息 */
293  async countTimeFinish() {
294    await window.app.info.updataDetailDiscountInfo()
295    window.app.info.productDetail.is_discount = 0
296    //隐藏倒计时
297    if (this.$date) this.$date.classList.add('d-none')
298    // 隐藏折扣
299    this.$off.classList.add('d-none')
300    this.$newPrice.innerHTML = ''
301    this.$newCostPrice.innerHTML = ''
302    this.$newPrice.innerText = ''
303    this.$newCostPrice.innerText = ''
304    this.render()
305  }
306  // 获取产品的优惠券
307  getProductCoupon() {
308    return this.utilts.request({
309      url: '/coupon/product-coupons',
310      method: 'GET',
311      params: {
312        product_id: window.app.info.productDetail.product_id
313      }
314    })
315  }
316  // 显示产品优惠券
317  async renderCouponList() {
318    const resData = await this.getProductCoupon()
319    this.counpList = resData.data
320    if (this.counpList.length > 0) {
321      this.$coupon.classList.remove('d-none')
322      const list = this.counpList.filter((_, i) => i <= 1)
323      this.setCouponList(list)
324      // 是否显示更多项
325      const $moreCoupon = this.$unit.querySelector('.unit-detail-price--detail')
326      if ($moreCoupon && this.counpList.length > 2) {
327        $moreCoupon.classList.remove('d-none')
328      }
329    }
330
331  }
332  // 设置产品优惠券节点
333  setCouponList(list) {
334    this.$discountList.innerHTML = ''
335    const $items = document.createElement('div')
336    $items.classList.add('unit-detail-price--discount-list_items')
337    list.forEach(data => $items.append(this.getCouponNode(data)))
338    this.$receive = document.createElement('div')
339    this.$receive.classList.add('unit-detail-price--discount-get--coupons')
340    if (window.innerWidth > 768) {
341      this.$receive.textContent = window.app.utilts.$t('Get coupons')
342    } else {
343      this.$receive.classList.add('iconfont', 'icon-action-left-lighter')
344    }
345    $items.append(this.$receive)
346    this.$discountList.append($items)
347    this.$receive.onclick = () => this.onShowCoupon()
348  }
349  // 生成产品优惠券节点
350  getCouponNode(data) {
351    const $node = document.createElement('div')
352    $node.classList.add('unit-detail-price--discount-list_item')
353    let innerHtml = this.getCouponHtml(data)
354    $node.innerHTML = innerHtml
355    this.$receive = $node.querySelector('.unit-detail-price--discount-list__item--receive')
356
357    return $node
358  }
359  getCouponHtml(data) {
360    const discount = data.discount_setting
361    const discountStr = discount.discount_type === 2 ? `$${this.utilts.toFixed(discount.discount_value / 100)}`
362      : (`${this.utilts.toFixed((1000 - discount.discount_value) / 10)}% ` + window.app.utilts.$t('Off'))
363    const usage_amount = data.usage_amount ? (window.app.utilts.$t('for order over') + ` $${this.utilts.toFixed(data.usage_amount / 100)}`) : window.app.utilts.$t('All Orders')
364    const htmlList = []
365    // Get xx% off for order over $xxx
366    htmlList.push(`<div class="unit-detail-price--discount-list__item-inner">`)
367    htmlList.push(`   <div class="unit-detail-price--discount-list__item--off">`)
368    htmlList.push(`     ` + window.app.utilts.$t('Get') + ` ${discountStr} ${usage_amount}`)
369    htmlList.push(`    </div>`)
370    htmlList.push(`</div>`)
371    return htmlList.join('')
372  }
373  /** 所有优惠券弹窗显示 */
374  async initAllCounponList() {
375    await new Load('/assets/plugins/coupon-list.js')
376    const couponList = new PluginCouponList(this.attrId, {
377      cols_col: 12,
378      cols_md: 6,
379      cols_xl: 6,
380      show_coupon: 1,
381      show_code: 1
382    })
383    this.coupon = await couponList.init()
384    this.$modalContent.append(this.coupon.$baseNode)
385  }
386  onShowCoupon() {
387    const modal = new Modal()
388    modal.init({
389      body: this.$modal,
390      title: window.app.utilts.$t('Get discount'),
391      size: 'lg',
392      className: 'coupon-modal',
393      isHideCancel: true,
394      isHideSubmit: true,
395      submitText: 'Confirm',
396      onCancel: () => modal.destroy()
397    }).open()
398    this.coupon.renderSvg()
399  }
400  render() {
401    this.initDicountInfo()
402    this.renderCouponList()
403    const wholesale = ScriptWholesalePrice.ins(this.attrId)
404    wholesale.init()
405  }
406}
407
408/**
409 * 批发价
410 */
411class ScriptWholesalePrice {
412  constructor(attrId) {
413    this.attrId = attrId
414    this.$unit = document.getElementById(`${this.attrId}`)
415
416    this.U = (suffix, isSelector = true) => `${isSelector ? '.' : ''}unit-detail-price${suffix}`
417
418    this.$wholesaleItem = this.$unit.querySelector('.unit-detail-price__wholesale--items')
419    this.$wholesales = this.$unit.querySelector('.unit-detail-price__wholesale')
420  }
421
422  /** 单例模式 */
423  static ins(attrId) {
424    if (!this.instance || window.app.utilts.checkDesign()) return this.instance = new ScriptWholesalePrice(attrId)
425    return this.instance
426  }
427
428  init() {
429    this.setWholesaleList()
430  }
431
432  setWholesaleList() {
433    // 批发价方式
434    const wholesale_method = window.app.info.productDetail.wholesale_method
435    // 批发价列表
436    const list = window.app.info.productDetail.wholesale
437    this.$unit.querySelector('[unit-type="price"]').style.setProperty('display','block')
438    this.$unit.querySelector('[unit-type="price"]').classList.remove('d-none')
439    if (wholesale_method && list.length <= 4) {
440      this.$wholesales.classList.remove('d-none')
441      let wholesaleHtml = ``
442      list.forEach(item => {
443        const newItem = this.setItem(item, wholesale_method)
444        wholesaleHtml += this.getHtml(newItem)
445      })
446      this.$wholesaleItem.innerHTML = wholesaleHtml
447    } else {
448      if (this.$unit.querySelector(this.U('__box-time')).classList.contains('d-none') && this.$unit.querySelector('[unit-type="price"]')) {
449        // 整个价格块隐藏
450        this.$unit.querySelector('[unit-type="price"]').classList.add('d-none')
451        this.$unit.querySelector('[unit-type="price"]').style.setProperty('display','none','important')
452      }
453    }
454  }
455
456  setItem(item, wholesale_method) {
457    const unit_price = this.getUnitPrice()
458    if (wholesale_method === 2) {
459      item.discount_limit = (100 - ((item.discount / 1000) / 10 * 100))
460      item.total_price = unit_price * (item.discount / 1000) / 10
461    } else {
462      item.discount_limit = unit_price ? ((unit_price - (item.discount / 100)) / unit_price * 100).toFixed(2) : 0
463      item.total_price = item.discount / 100
464    }
465    item.discount_limit = Number(Number(item.discount_limit).toFixed(2))
466    item.total_price = Number(Number(item.total_price).toFixed(2))
467    return item
468  }
469
470  getUnitPrice() {
471    const defail = window.app.info.productDetail
472    // 如果是折扣并且有原价
473    if (defail.is_discount == 1 && defail.discount_original_price) return defail.discount_original_price
474    // 如果是折扣并且没有原价
475    else if (defail.is_discount == 1 && !defail.discount_original_price) return defail.discount_sell_min_price
476    // 不是折扣返回最小销售价格
477    else return defail.min_price
478  }
479  getHtml(item) {
480    return `
481      <div class="unit-detail-price__wholesale--prices col-md-6 col-xl-3 
481col-12">
482        <div class="unit-detail-price__wholesale--number">${item.quantity}+ ${window.app.utilts.$t('Pieces')}</div>
483        <div class="unit-detail-price__wholesale--discont">${item.discount_limit}% ${window.app.utilts.$t('Off')}</div>
484        <div class="unit-detail-price__wholesale--price">
485          <span class="unit-detail-price__wholesale--i">$</span> 
486          <span>${item.total_price}</span> 
487        </div>
488      </div>
489    `
490  }
491}

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.