${function(){
return `
`
} ()}
`).replace(/\{received_discounts\}/g, ` `);
return `
`
}()}
${function(){
return `
${function() {
const selectedVariant = data.variant || data.variants[0];
const image = selectedVariant.image || data.product.image;
const imageWidth = image?.width || 120;
const imageHeight = image?.height || 120;
return `
`
}()}
${function() {
const defaultVariant = data.variants?.find(v => (v.available && v.is_hit_discount == true)) || data.variants?.[0];
const selectedVariant = data.variant || defaultVariant;
const isHasRrice = (selectedVariant.price || selectedVariant.price == 0) ? true : false;
return !!selectedVariant ? `
` : `
-
`;
}()}
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 && currentP
${data.map((variant) => {
return `
${function(){
const { original_price, received_discounts, picked_qty } = data;
const button_text = originData.setting.button.text;
const button_config = JSON.parse(originData.setting.button.config);
const button_action = originData.setting.button.redirect_page;
const text = originData.setting.price_text_config.text;
const price_config = JSON.parse(originData.setting.price_text_config.config);
const price_text = text.replace(/\{picked_qty\}/g, `${picked_qty}`).replace(/\{original_price\}/g, `
x${variant.quantity}
${variant.variant_title || variant.title}
`;
}).join('')}
${price_text}
${data[0].variant_title}
`
} ()}
x ${data.discount_min_purchase_qty}
${function() {
const currentProduct = data.product;
return (currentProduct.options || []).map((option, index) => {
const optionName = option.name || '';
const optionId = option.id || '';
const position = `option${index + 1}`;
return `
${function() {
const value = (data.originData && data.originData.value) || data.value;
const isHasValue = value ? true : false;
return `
`;
}).join('')
}()}
${value}
`
}()}
${(function() {
const productsInfo = data.product_info && data.product_info.product ? data.product_info.product : data;
return productsInfo.map(product => {
let price = product.price || 0;
let priceMin = product.price_min || 0;
let priceMax = product.price_max || 0;
let compareAtPriceMax = product.compare_at_price_max || 0;
let compareAtPrice = product.compare_at_price || 0;
let title = product.title || '';
let id = product.id || '';
let url = product.url || '';
let type = product.type || '';
let is_sold_out = false;
if (product.available == false && product.inventory_policy != 'continue') {
is_sold_out = true;
}
const soldOutLang1 = "Sold out";
const soldOutLang2 = "Sold out";
const discountType = data.discount_info ? data.discount_info.discount_type : product.discount_type;
const defaultVariantTitle = product.variants[0]?.title.replace('-', '/');
const variantDiscountInfo = product.variants[0]?.discount_info || {};
let discount_min_purchase_qty = 0;
if (discountType === "DT_CLASSIC_BUNDLE" && data.discount_info.enable_min_purchase_qty) {
discount_min_purchase_qty = data.discount_info.min_purchase_qty_type === "spu" ? product.discount_min_purchase_qty : product.variants[0].discount_info.discount_min_purchase_qty;
}
let imageWidth;
if (product.image.width) {
imageWidth = product.image.width;
} else {
imageWidth = "300px";
}
let imageHeight;
if (product.image.height) {
imageHeight= product.image.height;
} else {
imageHeight = "300px";
}
if (product.published) {
return `
`
} else {
return ``;
}
}).join('');
})()}