CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
2/21
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
CHANEL Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody ProCaseMall
00:00
00:00
2/21

Luxurious Lambskin Chanel Button Card Holder iPhone Case Crossbody

$24.98
$0.00
Save 0%
Choose a colorBlack
Please select a choose a color
Choose a model
Please select a choose a model
Quantity
/** @private {string} */ class SpzCustomAnchorScroll extends SPZ.BaseElement { static deferredMount() { return false; } constructor(element) { super(element); /** @private {Element} */ this.scrollableContainer_ = null; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { this.viewport_ = this.getViewport(); this.initActions_(); } setTarget(containerId, targetId) { this.containerId = '#' + containerId; this.targetId = '#' + targetId; } scrollToTarget() { const container = document.querySelector(this.containerId); const target = container.querySelector(this.targetId); const {scrollTop} = container; const eleOffsetTop = this.getOffsetTop_(target, container); this.viewport_ .interpolateScrollIntoView_( container, scrollTop, scrollTop + eleOffsetTop ); } initActions_() { this.registerAction( 'scrollToTarget', (invocation) => this.scrollToTarget(invocation?.caller) ); this.registerAction( 'setTarget', (invocation) => this.setTarget(invocation?.args?.containerId, invocation?.args?.targetId) ); } /** * @param {Element} element * @param {Element} container * @return {number} * @private */ getOffsetTop_(element, container) { if (!element./*OK*/ getClientRects().length) { return 0; } const rect = element./*OK*/ getBoundingClientRect(); if (rect.width || rect.height) { return rect.top - container./*OK*/ getBoundingClientRect().top; } return rect.top; } } SPZ.defineElement('spz-custom-anchor-scroll', SpzCustomAnchorScroll); const STRENGTHEN_TRUST_URL = "/api/strengthen_trust/settings"; class SpzCustomStrengthenTrust extends SPZ.BaseElement { constructor(element) { super(element); this.renderElement_ = null; } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } buildCallback() { this.xhr_ = SPZServices.xhrFor(this.win); const renderId = this.element.getAttribute('render-id'); SPZCore.Dom.waitForChild( document.body, () => !!document.getElementById(renderId), () => { this.renderElement_ = SPZCore.Dom.scopedQuerySelector( document.body, `#${renderId}` ); if (this.renderElement_) { this.render_(); } this.registerAction('track', (invocation) => { this.track_(invocation.args); }); } ); } render_() { this.fetchData_().then((data) => { if (!data) { return; } SPZ.whenApiDefined(this.renderElement_).then((apis) => { apis?.render(data); document.querySelector('#strengthen-trust-render-1539149753700').addEventListener('click',(event)=>{ if(event.target.nodeName == 'A'){ this.track_({type: 'trust_content_click'}); } }) }); }); } track_(data = {}) { const track = window.sa && window.sa.track; if (!track) { return; } track('trust_enhancement_event', data); } parseJSON_(string) { let result = {}; try { result = JSON.parse(string); } catch (e) {} return result; } fetchData_() { return this.xhr_ .fetchJson(STRENGTHEN_TRUST_URL) .then((responseData) => { if (!responseData || !responseData.data) { return null; } const data = responseData.data; const moduleSettings = (data.module_settings || []).reduce((result, moduleSetting) => { return result.concat(Object.assign(moduleSetting, { logos: (moduleSetting.logos || []).map((item) => { return moduleSetting.logos_type == 'custom' ? this.parseJSON_(item) : item; }) })); }, []); return Object.assign(data, { module_settings: moduleSettings, isEditor: window.self !== window.top, }); }); } } SPZ.defineElement('spz-custom-strengthen-trust', SpzCustomStrengthenTrust);
class SpzCustomDiscountBundleProducts extends SPZ.BaseElement { constructor(element) { super(element); this.xhr_ = SPZServices.xhrFor(this.win); this.getDiscountPriceApi = "\/api\/storefront\/promotion\/calculate\/discounted_price"; this.buyNowApi = "\/api\/checkout\/order"; this.batchAtcApi = "\/api\/cart\/batch"; // 款式信息集合 this.productStyleInfo = []; // 弹窗内选择款式集合 this.modalVariantInfo = []; this.show_classic_bundle_spu_style = false; this.bundleProducts = []; //捆绑商品 this.bundleConfig = {}; //下方按钮配置 this.discountId = ""; this.discountType = ""; this.discountInfo = ""; this.lineItems = []; this.tempCss = {}; this.renderQuickShop_ = this.win.SPZCore.Types.debounce(this.win, this.renderQuickShopModal.bind(this), 500); } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { this.setupAction_(); }; init(data = []) { this.productStyleInfo = data; } handleRequestError_(data) { this.showToast(data?.message || data?.errors?.[0] || 'Unknown error'); }; //外部组件调用传值 setBundleData(products, config = "", id = "", type = "", info = {}) { this.bundleProducts = products; if(config) { this.bundleConfig = config; this.discountId = id; this.discountType = type; this.discountInfo = info; if(type === 'DT_CLASSIC_BUNDLE' && info.enable_min_purchase_qty && info.min_purchase_qty_type == 'spu') { this.show_classic_bundle_spu_style = true; } // 经典捆绑初始化商品数据 if(type == 'DT_CLASSIC_BUNDLE') { this.productStyleInfo = products.map((item) => { return this.getFilteredVariants_(item, 'single'); }); } } } handleChangeSort() { const result = this.productStyleInfo.reduce((map, item) => { if (!map[item.product_id]) { map[item.product_id] = []; } map[item.product_id].push(item); return map; }, {}); Object.values(result).forEach((item) => { this.handleSpzVariantRender_(item, item[0].product_id); this.handleProductOption_(item[0].product_id, true); }); } // 调用spz-tag组件的doRender方法 handleSpzVariantRender_(data, id) { const spzVariantTag = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionSpzVariantTags-${id}`); spzVariantTag && SPZ.whenApiDefined(spzVariantTag).then((api) => { api.render(data, true); }); } // 执行经典捆绑最低购买数量更新 handleMinPurchaseQtyUpdate_(data, id) { const minPruchaseQty = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionMinPurchaseQty-${id}`); minPruchaseQty && SPZ.whenApiDefined(minPruchaseQty).then((api) => { api.render(data, true); }); } // 更新价格 updateProductPrice_(data) { const bottomBtnContainer = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionBottomContainer`); if (data.length == 0) { bottomBtnContainer && SPZ.whenApiDefined(bottomBtnContainer).then((api) => { const renderInfo = { setting: this.bundleConfig, ...{ original_price: 0, received_discounts: 0, picked_qty: 0 } } api.render({original_price: 0, received_discounts: 0}, true); }); return; } const reqBody = { discount_id: this.discountId, customer: { customer_id: '', email: '', }, sales_channel: { sale_channel_type: "online", sale_channel_id: '1319604' }, line_items: data } // 如果已经有一个请求在等待,那么取消这个请求 if (this.debounceTimer) { clearTimeout(this.debounceTimer); } this.debounceTimer = setTimeout(() => { this.xhr_.fetchJson(this.getDiscountPriceApi, { method: "post", body: reqBody }).then((res)=>{ // 更新商品列表价格 Object.keys(res.line_items).forEach((key) => { const currentProductPrice = SPZCore.Dom.scopedQuerySelector(document.body, `#appDiscountProductPrice-${key}`); currentProductPrice && SPZ.whenApiDefined(currentProductPrice).then((api) => { api.render(res.line_items[key], true); }); }); // 更新底部按钮总价/总折扣价 const picked_qty = data.reduce((acc, item) => { return acc + item.quantity; }, 0); bottomBtnContainer && SPZ.whenApiDefined(bottomBtnContainer).then((api) => { const data = { setting: this.bundleConfig, ...{ ...res.total_price, picked_qty } } api.render(data, true); }); }).catch((err)=>{ this.handleRequestError_(err); }).finally(()=>{ }) }, 100); } // 还原商品价格 resetProductPrice_(data) { const {price, compare_at_price, id} = data; const currentProductPrice = SPZCore.Dom.scopedQuerySelector(document.body, `#appDiscountProductPrice-${id}`); currentProductPrice && SPZ.whenApiDefined(currentProductPrice).then((api) => { api.render({total_received_discounts: price, total_price: compare_at_price}, true); }); } //处理与selector组件的交互 handleProductOption_(productId, show) { const currentProductOption = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionSelectOption-${productId}`); currentProductOption && currentProductOption.toggleAttribute('show', show); const productSelector = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionProductSelector`); productSelector && SPZ.whenApiDefined(productSelector).then((api) => { api.toggle_({option: productId, value: show}); }); } // 混搭弹窗内的前端库存校验 handleModalInventoryCheck_(data) { if(this.discountType == 'DT_MIX_MATCH_BUNDLE' || this.discountType == 'DT_CLASSIC_BUNDLE') { const currentVariantAddNum = this.modalVariantInfo.find((item) => item.variant_id == data.variant_id)?.quantity || 0; const quickShopBody = SPZCore.Dom.scopedQuerySelector(document.body, '#apps-discount-quick-shop-body'); if(!!data.variant && currentVariantAddNum == Number(data.variant.available_quantity)) { quickShopBody && quickShopBody.setAttribute('status', 'soldout'); } else { quickShopBody && quickShopBody.setAttribute('status', 'available'); } } else { return; } } // 添加商品子款式 renderVariantTag() { let variantInfo; const quickShopBody = SPZCore.Dom.scopedQuerySelector(document.body, '#apps-discount-quick-shop-body'); quickShopBody && SPZ.whenApiDefined(quickShopBody).then((api) => { variantInfo = api.getVariantsData(); const productId = variantInfo.product_id; const variantId = variantInfo.variant_id; const minPruchaseQtyRender = variantInfo.product.discount_min_purchase_qty || variantInfo.variant.discount_info.discount_min_purchase_qty; if(this.discountType === 'DT_MIX_MATCH_BUNDLE') { const index = this.productStyleInfo.findIndex((item) => item.variant_id == variantInfo.variant_id); if (index != -1) { this.productStyleInfo[index].quantity = Number(this.productStyleInfo[index].quantity) + Number(variantInfo.quantity); this.updateProductPrice_(this.productStyleInfo); } else { this.productStyleInfo.push(this.getFilteredVariants_(variantInfo)); // 若当前商