文章目录[隐藏]
WordPress文创商品柔性组合销售插件开发教程
一、项目概述与需求分析
在文创电商领域,消费者常常希望将不同的文创产品组合购买,例如将笔记本、书签和贴纸组合成"文房四宝"套装。本教程将指导您开发一个WordPress插件,实现文创商品的柔性组合销售功能。
核心需求:
- 允许管理员创建可自定义的商品组合
- 前端展示组合商品及价格计算
- 支持组合内商品的库存联动
- 提供灵活的价格策略(固定价、折扣价等)
二、插件基础结构搭建
首先,我们在WordPress的plugins目录下创建插件文件夹flexible-product-bundles,并创建主文件:
<?php
/**
* Plugin Name: 文创商品柔性组合销售插件
* Plugin URI: https://yourwebsite.com/
* Description: 允许创建和销售可自定义的文创商品组合
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('FPB_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FPB_PLUGIN_URL', plugin_dir_url(__FILE__));
define('FPB_VERSION', '1.0.0');
// 初始化插件
class Flexible_Product_Bundles {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('plugins_loaded', array($this, 'init'));
}
public function activate() {
// 创建必要的数据库表
$this->create_tables();
// 设置默认选项
update_option('fpb_version', FPB_VERSION);
flush_rewrite_rules();
}
public function deactivate() {
flush_rewrite_rules();
}
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'fpb_bundles';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
description text,
products text NOT NULL,
price_type varchar(50) DEFAULT 'fixed',
discount decimal(5,2) DEFAULT 0,
status tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
public function init() {
// 加载必要的文件
$this->load_dependencies();
// 初始化各个模块
if (is_admin()) {
$this->init_admin();
}
$this->init_frontend();
}
private function load_dependencies() {
// 加载后台管理类
require_once FPB_PLUGIN_DIR . 'includes/class-fpb-admin.php';
// 加载前端展示类
require_once FPB_PLUGIN_DIR . 'includes/class-fpb-frontend.php';
// 加载商品组合类
require_once FPB_PLUGIN_DIR . 'includes/class-fpb-bundle.php';
}
private function init_admin() {
new FPB_Admin();
}
private function init_frontend() {
new FPB_Frontend();
}
}
// 启动插件
Flexible_Product_Bundles::get_instance();
?>
三、后台管理界面开发
创建includes/class-fpb-admin.php文件,实现后台管理功能:
<?php
class FPB_Admin {
public function __construct() {
// 添加管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 保存组合数据
add_action('admin_post_save_fpb_bundle', array($this, 'save_bundle'));
// 加载脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
}
public function add_admin_menu() {
add_menu_page(
'文创商品组合',
'商品组合',
'manage_options',
'fpb-bundles',
array($this, 'render_bundles_page'),
'dashicons-products',
56
);
add_submenu_page(
'fpb-bundles',
'添加新组合',
'添加新组合',
'manage_options',
'fpb-add-bundle',
array($this, 'render_add_bundle_page')
);
}
public function enqueue_scripts($hook) {
if (strpos($hook, 'fpb-') === false) {
return;
}
wp_enqueue_style(
'fpb-admin-style',
FPB_PLUGIN_URL . 'assets/css/admin.css',
array(),
FPB_VERSION
);
wp_enqueue_script(
'fpb-admin-script',
FPB_PLUGIN_URL . 'assets/js/admin.js',
array('jquery', 'select2'),
FPB_VERSION,
true
);
wp_enqueue_style('select2-css', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css');
wp_enqueue_script('select2-js', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js', array('jquery'), '4.0.13', true);
// 本地化脚本
wp_localize_script('fpb-admin-script', 'fpb_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('fpb_nonce')
));
}
public function render_bundles_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'fpb_bundles';
$bundles = $wpdb->get_results("SELECT * FROM $table_name ORDER BY created_at DESC");
include FPB_PLUGIN_DIR . 'templates/admin/bundles-list.php';
}
public function render_add_bundle_page() {
// 获取所有商品
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'status' => 'publish'
);
$products = get_posts($args);
include FPB_PLUGIN_DIR . 'templates/admin/add-bundle.php';
}
public function save_bundle() {
// 验证nonce
if (!isset($_POST['fpb_nonce']) || !wp_verify_nonce($_POST['fpb_nonce'], 'save_fpb_bundle')) {
wp_die('安全验证失败');
}
global $wpdb;
$table_name = $wpdb->prefix . 'fpb_bundles';
$data = array(
'name' => sanitize_text_field($_POST['bundle_name']),
'description' => sanitize_textarea_field($_POST['bundle_description']),
'products' => json_encode($_POST['bundle_products']),
'price_type' => sanitize_text_field($_POST['price_type']),
'discount' => floatval($_POST['discount']),
'status' => intval($_POST['status'])
);
if (isset($_POST['bundle_id']) && !empty($_POST['bundle_id'])) {
// 更新现有组合
$wpdb->update($table_name, $data, array('id' => intval($_POST['bundle_id'])));
} else {
// 插入新组合
$wpdb->insert($table_name, $data);
}
wp_redirect(admin_url('admin.php?page=fpb-bundles&saved=1'));
exit;
}
}
?>
四、商品组合数据模型
创建includes/class-fpb-bundle.php,定义商品组合的数据结构和方法:
<?php
class FPB_Bundle {
private $id;
private $name;
private $description;
private $products;
private $price_type;
private $discount;
private $status;
public function __construct($bundle_id = null) {
if ($bundle_id) {
$this->load($bundle_id);
}
}
public function load($bundle_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'fpb_bundles';
$result = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name WHERE id = %d",
$bundle_id
));
if ($result) {
$this->id = $result->id;
$this->name = $result->name;
$this->description = $result->description;
$this->products = json_decode($result->products, true);
$this->price_type = $result->price_type;
$this->discount = $result->discount;
$this->status = $result->status;
return true;
}
return false;
}
/**
* 计算组合总价
* @return float 组合价格
*/
public function calculate_price() {
if (empty($this->products)) {
return 0;
}
$total = 0;
foreach ($this->products as $product_id) {
$product = wc_get_product($product_id);
if ($product) {
$total += $product->get_price();
}
}
// 应用折扣
if ($this->price_type === 'discount' && $this->discount > 0) {
$total = $total * (1 - $this->discount / 100);
}
return round($total, 2);
}
/**
* 获取组合中的商品信息
* @return array 商品信息数组
*/
public function get_products_info() {
$products_info = array();
if (empty($this->products)) {
return $products_info;
}
foreach ($this->products as $product_id) {
$product = wc_get_product($product_id);
if ($product) {
$products_info[] = array(
'id' => $product_id,
'name' => $product->get_name(),
'price' => $product->get_price(),
'image' => get_the_post_thumbnail_url($product_id, 'thumbnail'),
'link' => get_permalink($product_id)
);
}
}
return $products_info;
}
/**
* 检查组合库存
* @return bool 是否有库存
*/
public function check_stock() {
if (empty($this->products)) {
return false;
}
foreach ($this->products as $product_id) {
$product = wc_get_product($product_id);
if (!$product || !$product->is_in_stock()) {
return false;
}
}
return true;
}
// Getter方法
public function get_id() { return $this->id; }
public function get_name() { return $this->name; }
public function get_description() { return $this->description; }
public function get_products() { return $this->products; }
public function get_price_type() { return $this->price_type; }
public function get_discount() { return $this->discount; }
public function get_status() { return $this->status; }
}
?>
五、前端展示与交互实现
创建includes/class-fpb-frontend.php,处理前端展示和用户交互:
<?php
class FPB_Frontend {
public function __construct() {
// 短代码支持
add_shortcode('show_product_bundle', array($this, 'render_bundle_shortcode'));
// 添加到购物车钩子
add_action('wp_ajax_add_bundle_to_cart', array($this, 'add_bundle_to_cart'));
add_action('wp_ajax_nopriv_add_bundle_to_cart', array($this, 'add_bundle_to_cart'));
// 加载前端资源
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
public function enqueue_scripts() {
wp_enqueue_style(
'fpb-frontend-style',
FPB_PLUGIN_URL . 'assets/css/frontend.css',
array(),
FPB_VERSION
);
wp_enqueue_script(
'fpb-frontend-script',
FPB_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
FPB_VERSION,
true
);
wp_localize_script('fpb-frontend-script', 'fpb_frontend', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('fpb_frontend_nonce')
));
}
public function render_bundle_shortcode($atts) {
$atts = shortcode_atts(array(
'id' => 0,
), $atts, 'show_product_bundle');
$bundle_id = intval($atts['id']);
if (!$bundle_id) {
return '<p>请指定有效的组合ID</p>';
}
$bundle = new FPB_Bundle($bundle_id);
if (!$bundle->get_id()) {
return '<p>找不到指定的商品组合</p>';
}
ob_start();
include FPB_PLUGIN_DIR . 'templates/frontend/bundle-display.php';
return ob_get_clean();
}
public function add_bundle_to_cart() {
// 验证nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'fpb_frontend_nonce')) {
wp_die('安全验证失败');
}
$bundle_id = intval($_POST['bundle_id']);
$bundle = new FPB_Bundle($bundle_id);
if (!$bundle->get_id()) {
wp_send_json_error(array('message' => '商品组合不存在'));
}
// 检查库存
if (!$bundle->check_stock()) {
wp_send_json_error(array('message' => '部分商品库存不足'));
}
// 将组合中的商品添加到购物车
$products = $bundle->get_products();
$added_count = 0;
foreach ($products as $product_id) {
$added = WC()->cart->add_to_cart($product_id, 1);
if ($added) {
$added_count++;
}
}
if ($added_count === count($products)) {
wp_send_json_success(array(
'message' => '商品组合已成功添加到购物车',
'cart_url' => wc_get_cart_url()
));
} else {
wp_send_json_error(array('message' => '添加商品到购物车时出错'));
}
}
}
?>
六、前端模板设计
创建templates/frontend/bundle-display.php:
<?php
/**
* 商品组合前端展示模板
*/
$products_info = $bundle->get_products_info();
$total_price = $bundle->calculate_price();
$original_price = 0;
foreach ($products_info as $product) {
$original_price += $product['price'];
}
?>
<div class="fpb-bundle-container" data-bundle-id="<?php echo $bundle->get_id(); ?>">
<h2 class="bundle-title"><?php echo esc_html($bundle->get_name()); ?></h2>
<?php if ($bundle->get_description()): ?>
<div class="bundle-description">
<?php echo wp_kses_post($bundle->get_description()); ?>
</div>
<?php endif; ?>
<div class="bundle-products">
<h3>包含商品:</h3>
<div class="products-grid">
<?php foreach ($products_info as $product): ?>
<div class="product-item">
<a href="<?php echo esc_url($product['link']); ?>" target="_blank">
<?php if ($product['image']): ?>
<img src="<?php echo esc_url($product['image']); ?>" alt="<?php echo esc_attr($product['name']); ?>">
<?php endif; ?>
<h4><?php echo esc_html($product['name']); ?></h4>
<p class="price"><?php echo wc_price($product['price']); ?></p>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="bundle-pricing">
<div class="original-price">
单独购买总价:<del><?php echo wc_price($original_price); ?></del>
</div>
<div class="bundle-price">
组合优惠价:<strong><?php echo wc_price($total_price); ?></strong>
</div>
<?php if ($bundle->get_price_type() === 'discount' && $bundle->get_discount() > 0): ?>
<div class="discount-info">
立省 <?php echo $bundle->get_discount(); ?>%
<?php endif; ?>
</div>
<div class="bundle-actions">
<?php if ($bundle->check_stock()): ?>
<button class="add-bundle-to-cart-btn" data-bundle-id="<?php echo $bundle->get_id(); ?>">
添加到购物车
</button>
<a href="<?php echo wc_get_cart_url(); ?>" class="view-cart-btn" style="display:none;">
查看购物车
</a>
<?php else: ?>
<button class="out-of-stock-btn" disabled>
部分商品缺货
</button>
<?php endif; ?>
</div>
<div class="bundle-message" style="display:none;"></div>
</div>
## 七、JavaScript交互功能
创建`assets/js/frontend.js`,实现前端交互逻辑:
/**
- 文创商品组合销售插件前端交互脚本
*/
(function($) {
'use strict';
$(document).ready(function() {
// 添加组合到购物车
$(document).on('click', '.add-bundle-to-cart-btn', function(e) {
e.preventDefault();
var $button = $(this);
var bundleId = $button.data('bundle-id');
var $container = $button.closest('.fpb-bundle-container');
var $message = $container.find('.bundle-message');
var $viewCartBtn = $container.find('.view-cart-btn');
// 禁用按钮,显示加载状态
$button.prop('disabled', true).text('添加中...');
$message.hide().removeClass('success error');
// 发送AJAX请求
$.ajax({
url: fpb_frontend.ajax_url,
type: 'POST',
data: {
action: 'add_bundle_to_cart',
bundle_id: bundleId,
nonce: fpb_frontend.nonce
},
success: function(response) {
if (response.success) {
// 显示成功消息
$message.addClass('success').html(response.data.message).show();
$button.hide();
$viewCartBtn.show();
// 更新购物车数量
updateCartCount();
} else {
// 显示错误消息
$message.addClass('error').html(response.data.message).show();
$button.prop('disabled', false).text('添加到购物车');
}
},
error: function() {
$message.addClass('error').html('网络错误,请重试').show();
$button.prop('disabled', false).text('添加到购物车');
}
});
});
// 更新购物车数量显示
function updateCartCount() {
$.ajax({
url: fpb_frontend.ajax_url,
type: 'POST',
data: {
action: 'get_cart_count'
},
success: function(response) {
if (response.success) {
// 更新页面上的购物车数量
$('.cart-count').text(response.data.count);
}
}
});
}
// 商品选择交互
$(document).on('change', '.bundle-product-select', function() {
var $select = $(this);
var productId = $select.val();
var $container = $select.closest('.bundle-option');
var $priceDisplay = $container.find('.product-price');
if (productId) {
// 获取商品价格
$.ajax({
url: fpb_frontend.ajax_url,
type: 'POST',
data: {
action: 'get_product_price',
product_id: productId,
nonce: fpb_frontend.nonce
},
success: function(response) {
if (response.success) {
$priceDisplay.text(response.data.price).show();
}
}
});
} else {
$priceDisplay.hide();
}
// 重新计算总价
calculateBundleTotal();
});
// 计算组合总价
function calculateBundleTotal() {
var total = 0;
var discount = parseFloat($('.bundle-discount').val()) || 0;
$('.bundle-product-select').each(function() {
var productId = $(this).val();
if (productId) {
var $option = $(this).find('option:selected');
var price = parseFloat($option.data('price')) || 0;
total += price;
}
});
// 应用折扣
if (discount > 0) {
total = total * (1 - discount / 100);
}
// 更新显示
$('.bundle-total-price').text('¥' + total.toFixed(2));
}
});
})(jQuery);
## 八、CSS样式设计
创建`assets/css/frontend.css`,美化前端展示:
/**
- 文创商品组合销售插件前端样式
*/
/ 组合容器 /
.fpb-bundle-container {
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 25px;
margin: 20px 0;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
/ 组合标题 /
.bundle-title {
color: #333;
font-size: 24px;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 2px solid #f0f0f0;
}
/ 组合描述 /
.bundle-description {
color: #666;
line-height: 1.6;
margin-bottom: 25px;
font-size: 16px;
}
/ 商品网格 /
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.product-item {
border: 1px solid #eee;
border-radius: 6px;
padding: 15px;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.product-item:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.product-item img {
max-width: 100%;
height: 150px;
object-fit: cover;
border-radius: 4px;
margin-bottom: 10px;
}
.product-item h4 {
font-size: 16px;
margin: 10px 0;
color: #444;
}
.product-item .price {
color: #e74c3c;
font-weight: bold;
font-size: 18px;
}
/ 价格区域 /
.bundle-pricing {
background: #f9f9f9;
padding: 20px;
border-radius: 6px;
margin: 25px 0;
}
.original-price {
color: #999;
font-size: 16px;
margin-bottom: 10px;
}
.bundle-price {
font-size: 28px;
color: #e74c3c;
margin: 10px 0;
}
.bundle-price strong {
font-weight: 700;
}
.discount-info {
display: inline-block;
background: #ff6b6b;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
margin-top: 10px;
}
/ 操作按钮 /
.bundle-actions {
margin-top: 25px;
text-align: center;
}
.add-bundle-to-cart-btn,
.view-cart-btn,
.out-of-stock-btn {
display: inline-block;
padding: 15px 40px;
font-size: 18px;
font-weight: 600;
text-decoration: none;
border-radius: 50px;
transition: all 0.3s ease;
cursor: pointer;
border: none;
}
.add-bundle-to-cart-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.add-bundle-to-cart-btn:hover {
transform: translateY(-2px);
box-shadow: 0 7px 20px rgba(102, 126, 234, 0.4);
}
.view-cart-btn {
background: #27ae60;
color: white;
}
.view-cart-btn:hover {
background: #219653;
transform: translateY(-2px);
}
.out-of-stock-btn {
background: #95a5a6;
color: white;
cursor: not-allowed;
}
/ 消息提示 /
.bundle-message {
margin-top: 15px;
padding: 12px 20px;
border-radius: 6px;
text-align: center;
font-weight: 500;
}
.bundle-message.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.bundle-message.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
/ 响应式设计 /
@media (max-width: 768px) {
.products-grid {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 15px;
}
.bundle-title {
font-size: 20px;
}
.bundle-price {
font-size: 24px;
}
.add-bundle-to-cart-btn,
.view-cart-btn {
padding: 12px 30px;
font-size: 16px;
width: 100%;
}
}
/ 加载动画 /
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-right: 10px;
vertical-align: middle;
}
## 九、插件优化与扩展建议
### 9.1 性能优化
// 添加缓存机制
class FPB_Cache {
private static $cache_group = 'fpb_bundles';
public static function get_bundle($bundle_id) {
$cache_key = 'bundle_' . $bundle_id;
$bundle = wp_cache_get($cache_key, self::$cache_group);
if (false === $bundle) {
$bundle = new FPB_Bundle($bundle_id);
wp_cache_set($cache_key, $bundle, self::$cache_group, 3600); // 缓存1小时
}
return $bundle;
}
public static function clear_bundle_cache($bundle_id) {
$cache_key = 'bundle_' . $bundle_id;
wp_cache_delete($cache_key, self::$cache_group);
}
}
### 9.2 扩展功能建议
1. **智能推荐系统**:基于用户浏览历史推荐相关组合
2. **限时折扣**:为特定组合添加时间限制的折扣
3. **库存预警**:当组合商品库存低于阈值时发送通知
4. **组合分析报表**:统计各组合的销售数据
5. **API接口**:提供REST API供第三方系统调用
## 十、部署与使用说明
### 10.1 安装步骤
1. 将插件文件夹上传到`/wp-content/plugins/`目录
2. 在WordPress后台激活插件
3. 进入"商品组合"菜单创建您的第一个组合
4. 使用短代码`[show_product_bundle id="1"]`在页面中显示组合
### 10.2 使用示例
// 在主题文件中直接调用
$bundle = new FPB_Bundle(1);
if ($bundle->get_id()) {
echo '<h2>' . $bundle->get_name() . '</h2>';
echo '<p>组合价格:' . wc_price($bundle->calculate_price()) . '</p>';
}
### 10.3 注意事项
1. 确保WooCommerce插件已安装并激活
2. 定期备份数据库
3. 在生产环境使用前充分测试
4. 考虑组合商品的库存同步问题
## 结语
通过本教程,您已经学会了如何开发一个完整的WordPress文创商品柔性组合销售插件。这个插件不仅实现了基本的组合销售功能,还考虑了用户体验、性能优化和扩展性。您可以根据实际需求进一步扩展功能,比如添加组合推荐算法、社交媒体分享功能或与第三方物流系统集成。
开发过程中最重要的是理解用户需求,文创产品的消费者往往注重个性化和独特性,因此灵活的配置选项和美观的展示界面至关重要。希望这个插件能为您的文创电商业务带来价值,提升销售转化率和客户满意度。
**下一步建议:**
1. 添加多语言支持
2. 实现组合商品的图片预览
3. 开发移动端优化界面
4. 集成支付和物流跟踪功能
