326 lines
9.5 KiB
JavaScript
326 lines
9.5 KiB
JavaScript
/**
|
||
* 混装产品前端脚本
|
||
*
|
||
* 处理混装产品的用户交互和价格计算
|
||
*/
|
||
|
||
(function($) {
|
||
'use strict';
|
||
|
||
/**
|
||
* 混装产品处理器
|
||
*/
|
||
var YooneBundleHandler = {
|
||
|
||
/**
|
||
* 初始化
|
||
*/
|
||
init: function() {
|
||
this.bindEvents();
|
||
this.updatePricing();
|
||
},
|
||
|
||
/**
|
||
* 绑定事件
|
||
*/
|
||
bindEvents: function() {
|
||
var self = this;
|
||
|
||
// 商品选择变化
|
||
$(document).on('change', '.bundle-item-checkbox', function() {
|
||
self.onItemSelectionChange($(this));
|
||
});
|
||
|
||
// 数量变化
|
||
$(document).on('change', '#bundle-quantity', function() {
|
||
self.updatePricing();
|
||
});
|
||
|
||
// 数量按钮
|
||
$(document).on('click', '.qty-btn.plus', function() {
|
||
self.increaseQuantity();
|
||
});
|
||
|
||
$(document).on('click', '.qty-btn.minus', function() {
|
||
self.decreaseQuantity();
|
||
});
|
||
|
||
// 表单提交验证
|
||
$('form.cart').on('submit', function(e) {
|
||
if (!self.validateBundleSelection()) {
|
||
e.preventDefault();
|
||
return false;
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 商品选择变化处理
|
||
*/
|
||
onItemSelectionChange: function($checkbox) {
|
||
var $item = $checkbox.closest('.bundle-item');
|
||
|
||
if ($checkbox.is(':checked')) {
|
||
$item.addClass('selected');
|
||
} else {
|
||
$item.removeClass('selected');
|
||
}
|
||
|
||
this.updatePricing();
|
||
},
|
||
|
||
/**
|
||
* 增加数量
|
||
*/
|
||
increaseQuantity: function() {
|
||
var $input = $('#bundle-quantity');
|
||
var current = parseInt($input.val()) || 1;
|
||
var max = parseInt($input.attr('max'));
|
||
|
||
if (!max || current < max) {
|
||
$input.val(current + 1).trigger('change');
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 减少数量
|
||
*/
|
||
decreaseQuantity: function() {
|
||
var $input = $('#bundle-quantity');
|
||
var current = parseInt($input.val()) || 1;
|
||
var min = parseInt($input.attr('min')) || 1;
|
||
|
||
if (current > min) {
|
||
$input.val(current - 1).trigger('change');
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 更新价格显示
|
||
*/
|
||
updatePricing: function() {
|
||
var self = this;
|
||
var selectedItems = this.getSelectedItems();
|
||
var quantity = parseInt($('#bundle-quantity').val()) || 1;
|
||
|
||
if (selectedItems.length === 0) {
|
||
this.clearPricing();
|
||
return;
|
||
}
|
||
|
||
// 显示计算中状态
|
||
$('#bundle-original-total, #bundle-final-total').text(yoone_bundle_params.i18n.calculating);
|
||
|
||
// AJAX 请求计算价格
|
||
$.ajax({
|
||
url: yoone_bundle_params.ajax_url,
|
||
type: 'POST',
|
||
data: {
|
||
action: 'yoone_calculate_bundle_price',
|
||
nonce: yoone_bundle_params.nonce,
|
||
bundle_id: $('.yoone-bundle-options').data('bundle-id'),
|
||
selected_items: selectedItems,
|
||
quantity: quantity
|
||
},
|
||
success: function(response) {
|
||
if (response.success) {
|
||
self.displayPricing(response.data);
|
||
} else {
|
||
self.showError(response.data.message || yoone_bundle_params.i18n.error);
|
||
}
|
||
},
|
||
error: function() {
|
||
self.showError(yoone_bundle_params.i18n.error);
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 获取选中的商品
|
||
*/
|
||
getSelectedItems: function() {
|
||
var items = [];
|
||
|
||
$('.bundle-item-checkbox:checked').each(function() {
|
||
var $checkbox = $(this);
|
||
var productId = $checkbox.closest('.bundle-item').data('product-id');
|
||
var quantity = parseInt($checkbox.val()) || 1;
|
||
|
||
items.push({
|
||
product_id: productId,
|
||
quantity: quantity
|
||
});
|
||
});
|
||
|
||
return items;
|
||
},
|
||
|
||
/**
|
||
* 显示价格信息
|
||
*/
|
||
displayPricing: function(data) {
|
||
$('#bundle-original-total').text(data.original_total_formatted);
|
||
$('#bundle-final-total').text(data.final_total_formatted);
|
||
|
||
if (data.savings > 0) {
|
||
$('#bundle-savings .savings-amount').text(data.savings_formatted);
|
||
$('#bundle-savings').show();
|
||
} else {
|
||
$('#bundle-savings').hide();
|
||
}
|
||
|
||
// 更新产品价格(用于WooCommerce)
|
||
this.updateProductPrice(data.final_total);
|
||
},
|
||
|
||
/**
|
||
* 清空价格显示
|
||
*/
|
||
clearPricing: function() {
|
||
$('#bundle-original-total, #bundle-final-total').text('-');
|
||
$('#bundle-savings').hide();
|
||
},
|
||
|
||
/**
|
||
* 更新产品价格
|
||
*/
|
||
updateProductPrice: function(price) {
|
||
// 更新产品页面的价格显示
|
||
var formattedPrice = this.formatPrice(price);
|
||
$('.summary .price .amount').html(formattedPrice);
|
||
|
||
// 触发价格更新事件
|
||
$(document.body).trigger('yoone_bundle_price_updated', [price]);
|
||
},
|
||
|
||
/**
|
||
* 格式化价格
|
||
*/
|
||
formatPrice: function(price) {
|
||
// 这里应该使用WooCommerce的价格格式化
|
||
// 简单实现,实际应该从服务器获取格式化后的价格
|
||
return '$' + parseFloat(price).toFixed(2);
|
||
},
|
||
|
||
/**
|
||
* 验证混装选择
|
||
*/
|
||
validateBundleSelection: function() {
|
||
var selectedItems = this.getSelectedItems();
|
||
|
||
if (selectedItems.length === 0) {
|
||
this.showError(yoone_bundle_params.i18n.select_items);
|
||
return false;
|
||
}
|
||
|
||
// 检查必选商品
|
||
var hasError = false;
|
||
$('.bundle-item').each(function() {
|
||
var $item = $(this);
|
||
var $checkbox = $item.find('.bundle-item-checkbox');
|
||
|
||
if ($checkbox.prop('disabled') && !$checkbox.is(':checked')) {
|
||
hasError = true;
|
||
return false;
|
||
}
|
||
});
|
||
|
||
if (hasError) {
|
||
this.showError('请选择所有必需的商品');
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
/**
|
||
* 显示错误信息
|
||
*/
|
||
showError: function(message) {
|
||
var $messages = $('.validation-messages');
|
||
$messages.html('<p>' + message + '</p>').show();
|
||
|
||
// 3秒后自动隐藏
|
||
setTimeout(function() {
|
||
$messages.fadeOut();
|
||
}, 3000);
|
||
},
|
||
|
||
/**
|
||
* 隐藏错误信息
|
||
*/
|
||
hideError: function() {
|
||
$('.validation-messages').hide();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 价格计算器
|
||
*/
|
||
var PriceCalculator = {
|
||
|
||
/**
|
||
* 计算原始总价
|
||
*/
|
||
calculateOriginalTotal: function(items) {
|
||
// 这个方法在实际使用中应该通过AJAX从服务器获取
|
||
// 这里只是示例实现
|
||
return 0;
|
||
},
|
||
|
||
/**
|
||
* 应用折扣
|
||
*/
|
||
applyDiscount: function(total, discountType, discountValue) {
|
||
if (discountType === 'percentage') {
|
||
return total * (1 - discountValue / 100);
|
||
} else if (discountType === 'fixed') {
|
||
return Math.max(0, total - discountValue);
|
||
}
|
||
|
||
return total;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 库存检查器
|
||
*/
|
||
var StockChecker = {
|
||
|
||
/**
|
||
* 检查商品库存
|
||
*/
|
||
checkStock: function(productId, quantity, callback) {
|
||
$.ajax({
|
||
url: yoone_bundle_params.ajax_url,
|
||
type: 'POST',
|
||
data: {
|
||
action: 'yoone_check_bundle_stock',
|
||
nonce: yoone_bundle_params.nonce,
|
||
product_id: productId,
|
||
quantity: quantity
|
||
},
|
||
success: function(response) {
|
||
if (callback) {
|
||
callback(response.success, response.data);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 文档就绪时初始化
|
||
*/
|
||
$(document).ready(function() {
|
||
if ($('.yoone-bundle-options').length > 0) {
|
||
YooneBundleHandler.init();
|
||
}
|
||
});
|
||
|
||
// 暴露到全局作用域
|
||
window.YooneBundleHandler = YooneBundleHandler;
|
||
window.YoonePriceCalculator = PriceCalculator;
|
||
window.YooneStockChecker = StockChecker;
|
||
|
||
})(jQuery); |