1 2/**æ§è¡æä»¶ */ 3class ScriptDetailPattern extends Script { 4 constructor(params) { 5 super(params) 6 this.params = params 7 this.$dom = document.querySelector(`#${this.attrId}`) 8 this.modal = null 9 this.$main = this.$dom.querySelector('.unit-detail-pattern') 10 this.isM = window.innerWidth < 768 11 } 12 init() { } 13 /** ææºç«¯åå§å */ 14 initMobile() { 15 this.$modalBtn = this.$dom.querySelector('.unit-detail-pattern__modal-btn') 16 if (!this.$modalBtn) return 17 this.$modalBtn.addEventListener('click', () => { 18 let mode = 0 19 const isCart = window.app.info.productDetail.config.button_authority.includes('cart') 20 const isBuy = window.app.info.productDetail.config.button_authority.includes('order') 21 if (isCart && isBuy) mode = 1 22 else if (isCart) mode = 2 23 else if (isBuy) mode = 3 24 else mode = 0 25 window.app.info.renderDetailPattern(mode) 26 }) 27 } 28 29 render() { 30 if (!this.$main) return 31 this.$main.innerHTML = '' 32 new PatternDocument(this.$main).init() 33 new Pattern(this.attrId, this) 34 35 if (this.isM) this.initMobile() 36 } 37} 38/** 产ååæ°å¹é */ 39class Pattern { 40 constructor(attr_id, parent) { 41 this.parent = parent 42 this.attr_id = attr_id 43 this.activeAttr = {} 44 this.allAttr = {} 45 this.matchList = [] 46 this.matchInfo = {} 47 this.attrItemNode = document.querySelectorAll(`#${attr_id} [attr-item]`) 48 this.utilts = Utilts.ins() 49 // å¨åææå±æ§ 50 this.initAttr() 51 // å å¼å ç´ ï¼ å½åç±»åçæ¬¾å¼å ¶ä»é¡¹ 52 this.initBrotherAttr() 53 // è·åæææé ç»åï¼å¤æ¬¾å¼/忬¾å¼ï¼ 54 this.initMatchInfo() 55 this.initCheckDisabled() 56 } 57 // å¨åææå±æ§ 58 initAttr() { 59 const _this = this 60 if (this.attrItemNode) { 61 for (const $el of this.attrItemNode) { 62 // è·åäº§åæ¬¾å¼ç±»åid 63 const items_id = $el.getAttribute('attr-items') 64 _this.allAttr[items_id] = _this.allAttr[items_id] || [] 65 // å¨åæå±ç±»åçé项 66 _this.allAttr[items_id].push(new Attr($el, _this)) 67 } 68 } 69 } 70 // å¨åå å¼å ç´ 71 initBrotherAttr() { 72 Object.keys(this.allAttr).forEach(key => { 73 this.allAttr[key].forEach((item, index) => { 74 for (let i = 0; i < this.allAttr[key].length; i++) { 75 if (i !== index) { 76 item.brotherAttrList.push(this.allAttr[key][i]) 77 } 78 } 79 }) 80 }) 81 } 82 // åå¨å¹é æ¬¾å¼ attr_idsï¼æ¬¾å¼ç±»åid attr_detail_idsï¼ æ¬¾å¼åæ°id 83 initMatchInfo() { 84 const detail = window.app.info.productDetail 85 if (detail.pattern.length > 1) { 86 detail.pattern.forEach(item => { 87 // 款å¼åæ°å卿¶ä¸ºå¤æ¬¾å¼ 88 if (!!item.attr_ids) { 89 const ids = item.attr_detail_ids.split(',').filter(v => v) 90 this.matchList.push(ids) 91 } 92 }) 93 detail.price_id = 0 94 detail.quantity = 1 95 detail.weight = 0 96 detail.stock = 'none' 97 detail.is_pattern = false 98 // 忬¾å¼ 99 } else if (detail.pattern.length == 1) { 100 console.log('detail',detail); 101 // 忬¾å¼ 102 this.matchInfo = detail.pattern[0] 103 detail.is_pattern = true 104 detail.price_id = Number(this.matchInfo.id) 105 detail.quantity = 1 106 detail.weight = Number(this.matchInfo.weight) 107 detail.length = Number(this.matchInfo.length) 108 detail.width = Number(this.matchInfo.width) 109 detail.height = Number(this.matchInfo.height) 110 detail.stock = Number(this.matchInfo.stock) 111 if (window.app.script.ScriptDetailLogistics) { 112 window.app.script.ScriptDetailLogistics[0].shipment_id = this.matchInfo.shipment_ids 113 } 114 } 115 } 116 // æ£æ¥å±æ§æ¯å¦ç¦ç¨ 117 initCheckDisabled() { 118 // æ¯ä¸ªå±æ§é½æ£æ¥ä¸ä¸èªå·±æ¯å¦éè¦ç¦ç¨ 119 Object.keys(this.allAttr).forEach(itemsKey => { 120 // é¤äºåç±»å±æ§,è·åå ¶ä»æ¬¾å¼ç±»åæ¿æ´»ç屿§å¼ 121 const activeAttrList = Object.keys(this.activeAttr).filter(key => key !== itemsKey).map(key => this.activeAttr[key]) 122 123 // 符åå·²é屿§çæ°çæé ç»å 124 const newMatchList = this.matchList 125 .filter(items => { 126 let isTrue = true // é»è®¤åæ ¼ 127 activeAttrList.forEach(item => { 128 if (!items.includes(item)) isTrue = false 129 }) 130 return isTrue 131 })
132 this.allAttr[itemsKey].forEach(obj => { 133 obj.checkDisabled(newMatchList) 134 }) 135 }) 136 } 137 // è·åå¹é ä¿¡æ¯ 138 getMatchInfo() { 139 const detail = window.app.info.productDetail 140 detail.is_discount = detail.discount_attr.length > 0 ? 1 : 0 141 const activeAttrList = Object.keys(this.activeAttr).map(key => this.activeAttr[key]) 142 if (activeAttrList.length === detail.pattern_attr_list.length) { 143 let match_index 144 this.matchList.forEach((arr, index) => { 145 let isTrue = true 146 activeAttrList.forEach(id => { if (!arr.includes(id)) isTrue = false }) 147 if (isTrue) match_index = index 148 }) 149 this.matchInfo = detail.pattern[match_index] 150 detail.price_id = Number(this.matchInfo.id) 151 detail.weight = Number(this.matchInfo.weight) 152 detail.thumb = this.matchInfo.thumb_prefix || '' 153 detail.length = Number(this.matchInfo.length) 154 detail.width = Number(this.matchInfo.width) 155 detail.height = Number(this.matchInfo.height) 156 console.log('this.matchInfo1', this.matchInfo) 157 if (window.app.script.ScriptDetailLogistics) { 158 window.app.script.ScriptDetailLogistics[0].price_method = this.matchInfo.shipment_method 159 window.app.script.ScriptDetailLogistics[0].shipment_id = this.matchInfo.shipment_ids 160 window.app.script.ScriptDetailLogistics[0].info = { id: 0, price: '', region: '', time: '' } 161 window.app.script.ScriptDetailLogistics[0].init() 162 if (this.matchInfo.shipment_method !== 0 && this.matchInfo.shipment_method !== 3) { 163 window.app.script.ScriptDetailLogistics[0].updataInfoView() 164 } 165 } 166 } else { 167 this.matchInfo = {} 168 detail.price_id = 0 169 detail.thumb = '' 170 } 171 } 172 // æ¹åä»·æ ¼
173 changePrice() { 174 const detail = window.app.info.productDetail 175 // 妿å½åäº§åæ¯éæ¶ææ£ï¼ä¿®æ¹ææåçä»·æ ¼ 176 if (detail.is_discount) { 177 this.setDiscoutProductPrice(detail) 178 } else 179 this.setNormalProductPrice(detail) 180 } 181 182 /** 183 * è®¾ç½®ææ£äº§åæ¬¾å¼ä»·æ ¼ 184 * @param {*} detail 185 * @returns 186 */ 187 setDiscoutProductPrice(detail) { 188 if (!this.matchInfo.id) { 189 detail.stock = 'none' 190 detail.is_pattern = false 191 detail.off_rate = this.utilts.toFixed((1000 - detail.max_discount) / 10) 192 detail.discount_price = detail.min_price 193 } else { 194 // 妿å¹é ä¸éæ¶ææ£ä¿¡æ¯ï¼ä½ææ£å±æ§æ¾ä¸å°ç¸å ³ä¿¡æ¯ 195 // 表示å½å款å¼ä¸ææ 196 detail.stock = this.matchInfo.stock 197 const attr = detail.discount_attr.find(p => p.price_id === detail.price_id) 198 if (attr) { 199 detail.is_discount = 1 200 detail.is_pattern = true 201 detail.discount_original_price = this.matchInfo.selling_price 202 detail.off_rate = this.utilts.toFixed((1000 - attr.percent) / 10) 203 detail.discount_price = this.utilts.toFixed(this.matchInfo.selling_price * attr.percent / 1000) 204 } else { 205 detail.is_pattern = false 206 detail.is_discount = 0 207 this.setNormalProductPrice(detail) 208 } 209 } 210 } 211 212 /** 213 * 设置æ®é产åä»·æ ¼ 214 * @param {*} detail 215 */ 216 setNormalProductPrice(detail) { 217 if (this.matchInfo.id) {// 妿䏿¯éæ¶ææ£ 218 detail.is_pattern = true 219 detail.stock = this.matchInfo.stock 220 detail.min_price = this.matchInfo.selling_price 221 detail.max_price = 0 222 detail.min_cost_price = this.matchInfo.cost_price 223 detail.max_cost_price = 0 224 } else detail.is_pattern = false 225 let matchTotal = document.querySelector(`#${this.attr_id} .pm-total-price`) 226 // mainPrice 为å½å主产åçä»·æ ¼,ç»æé 产å使ç¨ç®ä¸èµ·è´ä¹°çæ»ä»· 227 window.app.info.productDetail.mainPrice = detail.min_price 228 let matchProductsTotal = window.app.info.productDetail.matchProductsTotal || 0 229 // 妿ææé 产åï¼è®¡ç®æ»ä»· 230 if (matchTotal) { 231 matchTotal.innerHTML = `$${(detail.min_price + matchProductsTotal).toFixed(2)}` 232 } 233 234 let matchOriginalTotal = document.querySelector(`#${this.attr_id} .pm-original-total-price`) 235 window.app.info.productDetail.mainOriginalPrice = detail.min_cost_price 236 let matchProductsOriginalTotal = window.app.info.productDetail.matchProductsOriginalTotal || 0 237 // 妿ææé 产åï¼è®¡ç®æ»ä»· 238 if (matchOriginalTotal) { 239 matchOriginalTotal.innerHTML = `$${(detail.min_cost_price + matchProductsOriginalTotal).toFixed(2)}` 240 } 241 } 242 // æ´æ°å¹é è§å¾ ï¼m端使ç¨ï¼ 243 updataAttrView() { 244 if (!this.parent.isM || !this.matchInfo.id) return 245 let html = '' 246 window.app.info.productDetail.pattern_attr_list.forEach(item => { 247 if (this.activeAttr[item.product_attr_id]) { 248 const attr = item.content 249 const value = item.attr_value.filter(x => x.id === Number(this.activeAttr[item.product_attr_id]))[0].content 250 html += `<span>${attr}: ${value}</span>` 251 } 252 }) 253 this.parent.$dom.querySelector('.unit-detail-pattern__attr-items').innerHTML = html 254 } 255} 256 257/** åä¸ªåæ°äº¤äº */ 258class Attr { 259 constructor($dom, parent) { 260 this.$dom = $dom 261 this.parent = parent 262 this.items_id = this.$dom.getAttribute('attr-items') 263 this.item_id = this.$dom.getAttribute('attr-item') 264 this.isDisabled = false 265 this.isActive = false 266 this.brotherAttrList = [] 267 this.$dom.addEventListener('click', () => this.setActive()) 268 this.isM = window.innerWidth < 768 269 } 270 /**æ¿æ´»å½å款å¼åæ° */ 271 setActive() { 272 // ç¦ç¹ç¶æ 273 if (this.isDisabled) return 274 // é«äº®ç¶æåæ¶ 275 if (this.isActive) { 276 delete this.parent.activeAttr[this.items_id] 277 this.cancelActive() 278 } else { 279 // ç¹äº®å½å屿§ 280 this.isActive = true 281 // åèµ·ç¹äº®æ¬¾å¼åæ°çidï¼æ¬¾å¼ï¼ 款å¼åæ°id 282 this.parent.activeAttr[this.items_id] = this.item_id 283 this.$dom.classList.add('active') 284 } 285 // 忬¾å ¶ä»åæ°åæ¶é«äº® 286 this.brotherAttrList.forEach(_this => { 287 _this.cancelActive() 288 }) 289 this.parent.initCheckDisabled() 290 this.parent.getMatchInfo() 291 this.parent.changePrice() 292 this.parent.updataAttrView() 293 if(this.isM){ 294 window.app.scriptCaller('ScriptProductDetail', 'setBtnDisable') 295 } 296 // å·æ°é¡µé¢æ°æ®,ä¸å·æ°èªå·±
297 window.app.info.renderDetailView(['ScriptDetailPattern']) 298 } 299 /** åæ¶é«äº® */ 300 cancelActive() { 301 this.isActive = false 302 this.$dom.classList.remove('active') 303 } 304 /** ç¦æ¢ç¶æ */ 305 setDisabled(val) { 306 this.isDisabled = val 307 if (this.isDisabled) this.$dom.classList.add('disabled') 308 else this.$dom.classList.remove('disabled') 309 } 310 // å¹é å¯éç»å 311 checkDisabled(matchList) { 312 // é»è®¤ç¦ç¨ 313 let isDisabled = true 314 // æ¯ä¸ªç»åä¸ææ²¡æå½å屿§ï¼ä»»ä½ä¸ä¸ªæï¼å°±ä¸ç¦ç¨ 315 matchList 316 .forEach(items => { 317 if (items.includes(this.item_id)) isDisabled = false 318 }) 319 this.setDisabled(isDisabled) 320 } 321} 322 323class PatternDocument { 324 constructor($main) { 325 this.$main = $main 326 this.productDetail = window.app.info.productDetail 327 this.pattern_attr_list = this.productDetail.pattern_attr_list || [] 328 this.utilts = window.app.utilts 329 } 330 331 init() { 332 this.$items = document.createElement('div') 333 this.$items.classList.add('unit-detail-pattern__items') 334 if (this.pattern_attr_list.length === 0) { 335 this.$items.classList.add('d-none') 336 const isDesign = this.utilts.checkDesign() 337 if (this.pattern_attr_list.length === 0 && isDesign) { 338 const $noData = document.createElement('div') 339 $noData.classList.add('alert', 'alert-light', 'border') 340 $noData.innerHTML = '请å¨åå°äº§å--产å管ç--æ·»å /ç¼è¾äº§å管ç' 341 } 342 } else { 343 this.pattern_attr_list.forEach(attrItem => { 344 const $patternItem = this.getAttrItem(attrItem) 345 this.$items.append($patternItem) 346 }) 347 348 this.$main.append(this.$items) 349 this.$main.append(this.getMobileHtml()) 350 } 351 } 352 // ææºç«¯ä½¿ç¨ 353 getMobileHtml() { 354 const $box = document.createElement('div') 355 const $btn = document.createElement('div') 356 const $attr = document.createElement('div') 357 const $attr_items = document.createElement('div') 358 const $span = document.createElement('span') 359 360 $box.classList.add('unit-detail-pattern__simple') 361 $btn.classList.add('unit-detail-pattern__modal-btn') 362 $attr.classList.add('unit-detail-pattern__attr') 363 $attr.innerHTML = 'Style:' 364 $attr_items.classList.add('unit-detail-pattern__attr-items') 365 $span.classList.add('iconfont', 'icon-action-left-lighter', 'unit-detail-pattern__modal-alert') 366 this.pattern_attr_list.forEach(item => { 367 const span = document.createElement('span') 368 span.innerHTML = item.content 369 $attr_items.appendChild(span) 370 }) 371 $attr.appendChild($attr_items) 372 $btn.appendChild($attr) 373 $btn.appendChild($span) 374 $box.appendChild($btn) 375 return $box 376 } 377 378 /** è·å款å¼ä¿¡æ¯ */ 379 getAttrItem(item) { 380 const $item = document.createElement('div') 381 $item.classList.add('unit-detail-pattern__item') 382 383 const $label = document.createElement('div') 384 $label.classList.add('unit-detail-pattern__label') 385 $label.innerText = item.content 386 387 const $value = document.createElement('div') 388 $value.classList.add('unit-detail-pattern__value') 389 390 const $checkbox = document.createElement('div') 391 $checkbox.classList.add('unit-detail-pattern__checkbox') 392 393 item.attr_value.forEach(child => { 394 const $attrItem = this.getAttrValue(item, child) 395 $checkbox.append($attrItem) 396 }) 397 $value.append($checkbox) 398 399 $item.append($label) 400 $item.append($value) 401 return $item 402 } 403 404 /** è·å款å¼å±æ§ä¿¡æ¯ */ 405 getAttrValue(item, child) { 406 const $attrItem = document.createElement('div') 407 $attrItem.classList.add('unit-detail-pattern__child') 408 $attrItem.setAttribute('attr-items', item.product_attr_id) 409 $attrItem.setAttribute('attr-item', child.id) 410 if (child.thumb_prefix && [2, 3].includes(item.display_mode)) { 411 $attrItem.classList.add('has-img') 412 const $em = document.createElement('em') 413 $em.classList.add('is-dark') 414 $em.innerHTML = child.content 415 $attrItem.append($em) 416 417 let iopcmd = { convert: { quality: 100 }, thumbnail: { type: 4, width: 100 } } 418 let query_arr = child.thumb_prefix.split('?') 419 if (query_arr.length > 1) { 420 let iopcmd_arr = query_arr[1].split('iopcmd=') 421 if (iopcmd_arr.length > 1) { 422 iopcmd_arr.shift() 423 iopcmd.query = 'iopcmd=' + iopcmd_arr.join('iopcmd=') 424 } 425 } 426 427 const $img = document.createElement('img') 428 $img.src = globalThis.Server.getTransferImgUrl(query_arr[0], iopcmd, 'webp', window.app.info.site) 429 $attrItem.append($img) 430 } 431 if (item.display_mode === 2) { 432 $attrItem.classList.add('hide-attr-text') 433 } 434 const $span = document.createElement('span') 435 $span.innerHTML = child.content 436 $attrItem.append($span) 437 return $attrItem 438 } 439}
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.