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: '372868' }, 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)); // 若当前商品已选中,更新商品价格 const currentProductOption = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionSelectOption-${productId}`); const isSelected = currentProductOption && currentProductOption.hasAttribute('selected'); isSelected && this.updateProductPrice_(this.productStyleInfo); } const selectedVariantsFilter = this.productStyleInfo.filter((item) => item.product_id == productId); this.handleSpzVariantRender_(selectedVariantsFilter, productId); this.handleProductOption_(productId, true); } else { if(this.discountInfo.enable_min_purchase_qty == true && this.discountInfo.min_purchase_qty_type == 'spu' && minPruchaseQtyRender > 1) { const index = this.modalVariantInfo.findIndex((item) => item.variant_id == variantId); if (index != -1) { this.modalVariantInfo[index].quantity = Number(this.modalVariantInfo[index].quantity) + 1; } else { this.modalVariantInfo.push(this.getFilteredVariants_(variantInfo, 'classic_spu')); } const modalVariantTag = SPZCore.Dom.scopedQuerySelector(document.body, '#promotionModalVariantTagRender'); modalVariantTag && SPZ.whenApiDefined(modalVariantTag).then((api) => { api.render(this.modalVariantInfo, true); }); this.handleModalInventoryCheck_(variantInfo); const selectedVariantsNum = this.modalVariantInfo.reduce((acc, item) => { return acc + item.quantity; }, 0); if(selectedVariantsNum == minPruchaseQtyRender) { this.handleSpzVariantRender_([this.getFilteredVariants_(variantInfo)], productId); this.productStyleInfo = this.productStyleInfo.filter((item) => item.product_id != productId).concat(this.modalVariantInfo); const renderData = this.productStyleInfo.filter((item) => item.product_id == productId).map((item) => { return { ...item, is_classic_bundle_product_list_variant_tag: true } }); const classicSpuTag = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionClassicSpuTags-${productId}`); classicSpuTag && SPZ.whenApiDefined(classicSpuTag).then((api) => { api.render(renderData, true); }); this.updateProductPrice_(this.productStyleInfo); const quickView = SPZCore.Dom.scopedQuerySelector(document.body, '#apps-discount-quick-view'); quickView && SPZ.whenApiDefined(quickView).then((api)=>{ api.close(); }); this.modalVariantInfo = []; } else { return; } } // this.productStyleInfo 中已存在与productId, variantId都相同的商品 则直接return 关闭弹窗 const isExist = this.productStyleInfo.some((item) => item.product_id == productId && item.variant_id == variantId); if (isExist) { const quickView = SPZCore.Dom.scopedQuerySelector(document.body, '#apps-discount-quick-view'); quickView && SPZ.whenApiDefined(quickView).then((api)=>{ api.close(); }); return; } // 若 this.productStyleInfo 中已存在与productId相同的商品,则不再添加 否则替换 const index = this.productStyleInfo.findIndex((item) => item.product_id == productId); if (index != -1) { this.productStyleInfo[index] = this.getFilteredVariants_(variantInfo); } else { this.productStyleInfo.push(this.getFilteredVariants_(variantInfo)); } const selectedVariantsFilter = this.productStyleInfo.filter((item) => item.product_id == productId); this.handleSpzVariantRender_(selectedVariantsFilter, productId); this.handleMinPurchaseQtyUpdate_({discount_min_purchase_qty: minPruchaseQtyRender}, productId); this.updateProductPrice_(this.productStyleInfo); } const quickView = SPZCore.Dom.scopedQuerySelector(document.body, '#apps-discount-quick-view'); quickView && SPZ.whenApiDefined(quickView).then((api)=>{ api.close(); }); }); } // 单变体点击添加按钮 renderSingleVariant(data) { const { product_id } = data; const currentProduct = this.bundleProducts.find((product) => product.id == product_id); // 若当前商品已存在,则不再添加 而是更新数量 const index = this.productStyleInfo.findIndex((item) => item.product_id == product_id); if (index != -1) { this.productStyleInfo[index].quantity = Number(this.productStyleInfo[index].quantity) + 1; this.updateProductPrice_(this.productStyleInfo); } else { this.productStyleInfo.push(this.getFilteredVariants_(currentProduct, 'single')); } const renderProductArr = this.productStyleInfo.filter((item) => item.product_id == product_id); this.handleSpzVariantRender_(renderProductArr, product_id); this.handleProductOption_(product_id, true); } // 过滤选中商品的子款式 获取有用的信息 product_id,variant_id,price,compare_at_price,quantity,title,variant_title getFilteredVariants_(data, type = '') { const { id, title, variants, inventory_tracking, inventory_policy, inventory_quantity, product_type } = data; const { product_id, variant_id, variant, quantity, product, discount_min_purchase_qty } = data; const isSingle = type == 'single'; const variantData = isSingle ? (variants[0] || data) : variant; const productData = isSingle ? data : product; let item_quantity = 0; if (this.discountType === 'DT_MIX_MATCH_BUNDLE') { item_quantity = isSingle ? 1 : Number(quantity); } else if (type === 'classic_spu') { item_quantity = 1; } else { item_quantity = discount_min_purchase_qty || productData.discount_min_purchase_qty || variantData.discount_info.discount_min_purchase_qty || 1; } return { product_id: isSingle ? id : product_id, variant_id: variantData?.id || '', price: variantData?.price || '0.00', compare_at_price: variantData?.compare_at_price || '0.00', quantity: item_quantity, inventory_tracking: productData.inventory_tracking, inventory_policy: productData.inventory_policy, inventory_quantity: productData.inventory_quantity, product_type: productData.product_type || this.bundleProducts.find((item) => item.id == product_id)?.product_type || this.bundleProducts.find((item) => item.id == id)?.product_type || '', title: productData.title, variant_title: variantData?.options.map((option) => option.value).join('/') || '', is_multi_style: productData.variants.length > 1, } } handleLoading_ (event) { const { type, action } = event; const loadingElementId = type === 'product' ? '#discount-match-drawer-products_loading' : '#apps-discount-whole-loading'; const loadingElement = document.querySelector(loadingElementId); if (loadingElement) { SPZ.whenApiDefined(loadingElement).then((api) => { if (action === 'show') { api.show_(); } else { api.close_(); } }); } } handleSelectProduct(productArr) { // 从this.productStyleInfo 过滤出选中的商品 const selectedProducts = this.productStyleInfo.filter((item) => productArr.includes(item.product_id)); this.updateProductPrice_(selectedProducts); } // 渲染加购弹窗内容 async renderQuickShopModal(data){ this.handleLoading_({type: 'whole', action: 'show'}); this.xhr_.fetchJson(`/api/storefront/promotion/landing_page/product?product_id=${data.product_id}&discount_id=${this.discountId}&apply_scenario=1`, { method: "get", }).then(async(res)=>{ //flash主题放block有层级问题 if(/Flash/.test(window.C_SETTINGS.theme.merchant_theme_name) && document.querySelector(".productInfoSection")) { this.tempCss.zIndex = document.querySelector(".product-info-body").style.zIndex; document.querySelector('.product-info-body').style.zIndex="1048"; } this.handleLoading_({type: 'whole', action: 'close'}); const $quickShop = await SPZ.whenApiDefined(document.querySelector('#apps-discount-quick-view-render')); // 定义默认渲染的子款式 const selectedVariant = res.product.variants.find((v)=> (v.available && v.is_hit_discount)) || res.product.variants[0]; let selectedValues = {}; selectedVariant.options.length && selectedVariant.options.forEach(item => { selectedValues[item.name] = item.value; }) // 默认选中的 子款式、 options res.product.defaultSelectValues = selectedValues; let data = {...res.product, product:res.product, selectedVariant, show_classic_bundle_spu_style: this.show_classic_bundle_spu_style, discountType: this.discountType}; $quickShop.render(data); // 打开加购弹窗 SPZ.whenApiDefined(document.querySelector(`#apps-discount-quick-view`)).then((api)=>{ api.open(); }); }).catch((err)=>{ this.handleLoading_({type: 'whole', action: 'close'}); }) } // 删除商品子款式 deleteVariantTag(data) { const { product_id, variant_id } = data; if(this.discountInfo.enable_min_purchase_qty == true && this.discountInfo.min_purchase_qty_type == 'spu') { const modalProductVariants = this.modalVariantInfo.filter((item) => item.product_id == product_id && item.variant_id != variant_id); const modalVariantTag = SPZCore.Dom.scopedQuerySelector(document.body, '#promotionModalVariantTagRender'); modalVariantTag && SPZ.whenApiDefined(modalVariantTag).then((api) => { api.render(modalProductVariants, true); }); this.handleModalInventoryCheck_(data); this.modalVariantInfo = modalProductVariants; return; } const currentProductVariants = this.productStyleInfo.filter((item) => item.product_id == product_id && item.variant_id != variant_id); this.handleSpzVariantRender_(currentProductVariants, product_id); // 更新selectedVariants this.productStyleInfo = this.productStyleInfo.filter((item) => item.variant_id != variant_id); if(currentProductVariants.length > 0) { // currentProductVariants 中只要有一项是多款式商品,就更新价格 const isMultiStyle = currentProductVariants.some((item) => item.is_multi_style); isMultiStyle && this.updateProductPrice_(this.productStyleInfo); } else { this.handleProductOption_(product_id, false); this.resetProductPrice_(this.bundleProducts.find((item) => item.id == product_id)); } } // 加购弹窗未参与活动 加购按钮不可点击 TODO 拆出来 handleNotHitDiscount_(data) { const $quickShopBody = document.querySelector('#apps-discount-quick-shop-body'); //当前子框式未命中活动 if(data.variant.is_hit_discount == false) { $quickShopBody.setAttribute('variantstatus', 'notHitDiscount') } else { $quickShopBody.setAttribute('variantstatus', '') } } setupAction_() { // 子款式 未参与活动 this.registerAction('handleNotHitDiscount', (invocation) => { const data = invocation.args.data; this.handleNotHitDiscount_(data); }); // 渲染加购弹窗 this.registerAction('renderQuickShop', (invocation) => { const data = invocation.args; this.renderQuickShop_(data); }); this.registerAction('renderSingleVariant', (invocation) => { const data = invocation.args; this.renderSingleVariant(data); }); this.registerAction('getVariantInfo', (invocation) => { this.renderVariantTag(); }); this.registerAction('deleteVariantTag', (invocation) => { const data = invocation.args; this.deleteVariantTag(data); }); this.registerAction('getSelectedProduct', (invocation) => { const data = invocation.args.data; this.handleSelectProduct(data); }); //TODO 加购下单逻辑单独拆组件 this.registerAction('handleClick', (data) => { if(this.discountType == 'DT_CLASSIC_BUNDLE') { this.lineItems = this.productStyleInfo; } else { const selectedOptions = SPZCore.Dom.scopedQuerySelectorAll(document.body, '[id^="promotionSelectOption-"]'); const idArr = [...selectedOptions].reduce((acc, item) => { if (item.hasAttribute('selected')) { const optionValue = item.getAttribute('option'); if (optionValue) { acc.push(optionValue); } } return acc; }, []); this.lineItems = this.productStyleInfo.filter((item) => idArr.includes(item.product_id)); } const action = data.args.action === "cart"; if(action) { //add to cart this.xhr_ .fetchJson(this.batchAtcApi, { method: 'POST', body: { line_items: this.lineItems.map((item) => { return { product_id: item.product_id, variant_id: item.variant_id, quantity: Number(item.quantity) } }) } }) .then((data) => { setTimeout(() => { window.location.href = '/cart'; }); }) .catch(async (error) => { await error.then((data) => { this.handleRequestError_(data); }); }); } else { //checkout this.xhr_ .fetchJson(this.buyNowApi, { method: 'POST', body: { line_items: (this.lineItems || []).map((product) => { return { quantity: Number(product.quantity), variant_id: product.variant_id, note: product.note || '', properties: product.properties || {} } }), refer_info: { source: 'buy_now' } } }) .then(async (data) => { if (data.state === 'success') { window.location.href = data.data?.checkout_url; } this.handleRequestError_(data); }) .catch(async (error) => { await error.then((data) => { this.handleRequestError_(data); }); }); } }); this.registerAction('resetModalVariantInfo', () => { //flash主题放block有层级问题 if(/Flash/.test(window.C_SETTINGS.theme.merchant_theme_name) && document.querySelector(".productInfoSection")) { document.querySelector('.product-info-body').style.zIndex = this.tempCss.zIndex; } this.modalVariantInfo = []; }); this.registerAction('handleModalInventoryCheck', (invocation) => { const data = invocation.args.data; this.handleModalInventoryCheck_(data); }); }; }; SPZ.defineElement('spz-custom-discount-bundle-products', SpzCustomDiscountBundleProducts);
class SpzCustomDiscountBundle extends SPZ.BaseElement { constructor(element) { super(element); this.xhr_ = SPZServices.xhrFor(this.win); this.variant_id = '2b20aa4e-47f3-419c-a9e6-80c4829a9911'; this.discountCardApi = "\/api\/storefront\/promotion\/product_details_page\/card"; this.productsApi = "\/api\/storefront\/promotion\/product_page\/product\/list"; this.bundleRenderElement = "appDiscountProductBundle"; this.model = { loading: false, page: 2, limit: 20, params: { count: 0, has_more: false, sort: { by: "price", direction: "asc" } } } this.discountId = ""; this.discountType = ""; this.bundleProducts = []; //捆绑活动商品 this.buttomConfig = {};//总价及下方按钮配置 this.renderDiscount = this.win.SPZCore.Types.debounce(this.win, this.discountHandel.bind(this) , 500); } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } async getDiscountCardList() { const productId = '81037c28-2560-4bd5-897b-ee825b228bb3'; const variantId = this.variant_id; const reqBody = { product_id: productId, variant_id: variantId, discount_types: ["DT_CLASSIC_BUNDLE","DT_MIX_MATCH_BUNDLE"], discount_methods: ["DM_AUTOMATIC"], customer: { customer_id: '', email: '', } } const data = await this.xhr_.fetchJson(this.discountCardApi, { method: "post", body: reqBody }).then(res => { return res; }).catch(err => { console.error(err); }) return data; }; async discountHandel() { const $bundle = document.querySelector(".app-discount-bundle-inner"); $bundle && SPZCore.Dom.removeElement($bundle); const data = await this.getDiscountCardList(); if(!data.discount_info || data.discount_info.discount_id === "0") { return; } //变量赋值 this.bundleProducts = data.product_info.product; this.buttomConfig = data.product_setting; this.discountId = data.discount_info.discount_id; this.discountType = data.discount_info.discount_type; this.model.params ={ count: data.product_info.count, has_more: data.product_info.has_more, sort: data.product_info.sort } //给捆绑组件传值 SPZ.whenApiDefined(document.getElementById("appDiscountBundleProductsFunc")).then((api) => { api.setBundleData(this.bundleProducts, this.buttomConfig, this.discountId, this.discountType, data.discount_info); }) document.querySelector(".app_discount_bundle").dataset.discountType = data.discount_info.discount_type; SPZ.whenApiDefined(document.getElementById(this.bundleRenderElement)) .then(apis => { apis.render(data,true).then(() => { SPZ.whenApiDefined(document.getElementById("bundleProductsRender")).then((api) => { api.render(data,true).then(() => { this.bindEvent_(); if(this.bundleProducts.length < 5) { document.querySelector(".app-discount-bundle-arrow-left").style.display="none"; document.querySelector(".app-discount-bundle-arrow-right").style.display="none"; } //经典捆绑渲染按钮 if(this.discountType === "DT_CLASSIC_BUNDLE") { SPZ.whenApiDefined(document.getElementById("promotionBottomContainer")).then((api) => { const buttonData = { setting: this.buttomConfig, ...data.product_info.total_price } api.render(buttonData, true); }) } }) }) }) .then(() => { document.querySelector(".app-discount-bundle-inner").classList.add("discount_bundle_" + data.product_setting.template_type || "vertical"); }); }); //本地调试 放商详block里 const isSection = document.querySelector( 'div[data-section-type^="shoplazza://apps/publicapp/blocks/discount_bundle/"] .app_discount_bundle' ); if(!isSection) { document.querySelector(".app_discount_bundle").classList.add("productInfoSection"); } }; // 获取加载的商品数据,拼接html模板 async loadData(cb) { // 请求数据 this.model.loading = true; //查询活动商品接口 const reqBody = { discount_id: this.discountId, page: this.model.page, limit: this.model.limit, "apply_scenario": "AS_ENTITLED_PRODUCT", sort: this.model.params.sort, sales_channel: { sale_channel_type: "online", sale_channel_id: '372868' }, product_id: '81037c28-2560-4bd5-897b-ee825b228bb3' } this.xhr_.fetchJson(this.productsApi, { method: "post", body: reqBody }).then(async(res)=>{ const count = res.count; this.model.params.has_more = res.has_more; if (count > 0) { this.model.page++; if (res.products && res.products.length > 0) { let products = res.products.map((product) => { return { ...product, url: appDiscountUtils.globalizePath(product.url), image_padding_bottom: appDiscountUtils.image_padding_bottom(product.image.width, product.image.height,'no-limit'), discount_type: this.discountType } }); // 获取商品列表渲染模板, dom挂载 const $content = document.querySelector(".app-discount-bundle-products"); this.templates_ = SPZServices.templatesForDoc(); this.templates_.renderTemplate(document.querySelector('#appDiscountBundleProductsTemplate'), products).then((el) => { const childNodes = el.querySelectorAll('.as-render-product-item'); if (childNodes && childNodes.length > 0) { $content.append(...childNodes); } }).then(() => { //重新渲染ljs-selector const productSelector = SPZCore.Dom.scopedQuerySelector(document.body, `#promotionProductSelector`); productSelector && SPZ.whenApiDefined(productSelector).then((api) => { api.init(); }); }); this.bundleProducts = [...this.bundleProducts, ...res.products]; SPZ.whenApiDefined(document.getElementById("appDiscountBundleProductsFunc")).then((api) => { api.setBundleData(this.bundleProducts); }) // 监听load去掉灰色背景 document.dispatchEvent(new CustomEvent('fire.load.img')); // 触发懒加载 cb && cb(products); window.lazyLoadInstance && window.lazyLoadInstance.update(); } } this.model.loading = false; }).catch((err)=>{ console.error(err); this.model.loading = false; }) }; setupAction_() { this.registerAction('shiftMove', (data) => { const $el = document.querySelector(".app-discount-bundle-products"); const action = data.args.direct === "right"; const scrollwidth = action ? $el.offsetWidth : -$el.offsetWidth; $el.scrollBy({ left: scrollwidth, behavior: 'smooth' }); }); }; bindEvent_() { // 监听子款式切换,重新渲染 document.addEventListener('dj.variantChange', async(event) => { const variant = event.detail.selected; if (variant.product_id == '81037c28-2560-4bd5-897b-ee825b228bb3') { this.variant_id = variant.id; } this.renderDiscount(); }); // 监听滚动,请求数据 const $el = document.querySelector(".app-discount-bundle-products"); if($el) { $el.addEventListener("scroll", this.win.SPZCore.Types.debounce( this.win, () => { const isLeft = $el.scrollLeft === 0; const isRightEnd = $el.scrollLeft + $el.offsetWidth + 10 >= $el.scrollWidth; const isBottomEnd = $el.scrollTop + $el.clientHeight + 10 >= $el.scrollHeight; const isEnd = isBottomEnd && isRightEnd; if(isEnd && this.model.params.has_more && !this.model.loading) { this.loadData(); } }, 50 )) }; }; buildCallback() { this.setupAction_(); }; mountCallback() { this.renderDiscount(); this.bindEvent_(); }; } SPZ.defineElement('spz-custom-discount-bundle', SpzCustomDiscountBundle);
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
1 / 36
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)
50% OFF

⏳ Limited time 50% off! 🔥Racerback Wide Shoulder Straps Seamless Bodysuit(The more you buy, the higher the discount)

$19.99 $39.99
0 sold
Color💶The more you buy, the higher the discount💶
SIZE
Size Table
Qty

💕Every girl should have such a molding garment in her closet💫

Featuring targeted shaping, our bodysuit smooths and refines your midsection, creating a stunning silhouette that boosts your confidence in any outfit.

Get perfect body-hugging shape and breathability with this shapewear!!

Its whisper-soft, seamless construction make this sculpting piece an essential for enhancing your body's natural shape. Perfect for layering under clothes or wearing alone as a super flattering all-in-one style.

Our bodysuit offers excellent bust support, allowing you to go bra-free while ensuring you feel confident and comfortable in any outfit. Embrace your shape with ease!

You can tucked this bodysuit tank top for going out into pants or skirt, shorts, jeans. This body suit also perfect with jacket, blazer or cardigan, smooth professional look with confidence, you'll get lots of compliments.

Flaunt your curves with confidence in our Shapewear. The delicate lace hugs your body.smoothing out any imperfections and enhancingyour natural curves. Get ready to turn headsand feel your best in this must-have piece.

Ours adopts seamless design with no painful and uncomfortable steel brackets The support it provides is so good that you don't even have to wear a bra, it also provides support for larger breasts. The built-in bra supports and improves your breasts. The stretchy fabric ensures a snug fit without discomfort, pinching or itching.

Say hello to pretty bodysuit that actually sculpts and defines your curves for that snatched look. With the same smoothing technology found in each of our hourglass-enhancing shape suits, you'll look snatched, cute and sexy all at the same time.

Like all our bodysuits, pair this with your favorite bottoms OR wear it under a dress for smooth, sculpted curves.

accentuates your body in all of the right places giving you an unmatched  smoother,  slimmer look!

Imagine the pure joy you will feel when you see how good you look in this. The rush of endorphins you get when you feel and look good is unmatched!  gives you all of the confidence you will ever need!

High-quality Polyamide fabric delivers bodysuit with outstanding shaping performance and is designed to move with you, so you feel comfy and not at all confined. Comfortable for all-day wear.

This waist bodysuit for women is made of double-layer stretchy fabric, and the inner layer is made of stretchy mesh fabric to Increase breathable comfort. It wraps and tightens your tummy and back remarkably, will hide the bumps and bulges on both sides to slim your waist, and gives you a beautiful hourglass figure.

Moderate compression pressure will tighten your flabby fat down to help you have a slimmer look while enhancing your natural curve. Smooth belly bulges and shrinks waistline, make your body no lumps or bumps or bulks. This girdles shapewear also with an open crotch design, which is very convenient when going to the bathroom, no need to take all the clothes off. 

2 wide and adjustable elastic straps can reduce shoulder pressure and make you feel more comfortable. Backless design perfect for wearing under open back tops and dresses.

⚡️Stock sells fast - get yours today!

❤️Thank you very much for visiting our store. Have a nice shopping day!❤️