首页 / 跨境电商轻量软件 / 实操指南:实现商品多属性变体接口的5个设计要点

实操指南:实现商品多属性变体接口的5个设计要点

实操指南:实现商品多属性变体接口的5个设计要点

引言:为什么商品多属性变体如此重要?

在当今的电商环境中,商品多属性变体已成为在线商店的标配功能。无论是服装的颜色和尺码组合,还是电子产品的配置选项,多属性变体系统都能显著提升用户体验和销售转化率。对于WordPress开发者而言,实现一个高效、可扩展的多属性变体接口是构建专业电商网站的关键技术挑战。

本文将从WordPress开发者的角度出发,深入探讨实现商品多属性变体接口的5个核心设计要点。我们将结合WooCommerce的实际案例,为行业新人和程序员提供可操作的开发指导。

设计要点一:建立灵活的数据结构模型

理解WooCommerce的数据结构基础

在WordPress生态中,WooCommerce是最流行的电商插件,其数据模型为我们提供了良好的参考基础。WooCommerce将产品分为简单产品、可变产品、分组产品和外部/关联产品四种类型。其中,可变产品(Variable Product)正是多属性变体的实现载体。

// WooCommerce可变产品的基本数据结构示例
class WC_Product_Variable extends WC_Product {
    // 产品变体数组
    protected $children = null;
    
    // 产品属性数组
    protected $attributes = array();
    
    // 获取所有变体
    public function get_children() {
        // 实现逻辑
    }
    
    // 获取产品属性
    public function get_attributes() {
        // 实现逻辑
    }
}

设计可扩展的属性系统

一个优秀的多属性系统应该具备以下特点:

  1. 动态属性定义:允许商家自定义属性类型(颜色、尺寸、材质等)
  2. 层级结构:支持属性分组和子属性
  3. 多语言支持:为国际化电商做好准备
  4. 性能优化:合理设计数据库表结构,避免过度连接查询
// 自定义属性数据表设计示例
global $wpdb;

$attribute_table = $wpdb->prefix . 'custom_attributes';
$attribute_terms_table = $wpdb->prefix . 'custom_attribute_terms';
$product_attribute_table = $wpdb->prefix . 'product_attributes';

// 创建表的SQL语句
$sql = "CREATE TABLE IF NOT EXISTS {$attribute_table} (
    attribute_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    attribute_name VARCHAR(200) NOT NULL,
    attribute_slug VARCHAR(200) NOT NULL,
    attribute_type VARCHAR(50) DEFAULT 'select',
    attribute_order INT DEFAULT 0,
    PRIMARY KEY (attribute_id),
    UNIQUE KEY attribute_slug (attribute_slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";

实现属性与变体的关联

在数据库层面,我们需要建立产品、属性和变体之间的多对多关系。这种设计允许一个属性被多个产品使用,一个产品拥有多个属性,一个变体是特定属性值的组合。

// 变体与属性关联的中间表示例
class Product_Variant {
    private $variant_id;
    private $product_id;
    private $attributes = array(); // 属性值对数组
    private $sku;
    private $price;
    private $stock_quantity;
    
    // 根据属性组合查找变体
    public static function find_variant_by_attributes($product_id, $attributes) {
        global $wpdb;
        
        $query = "SELECT v.variant_id FROM {$wpdb->prefix}product_variants v
                  JOIN {$wpdb->prefix}variant_attributes va ON v.variant_id = va.variant_id
                  WHERE v.product_id = %d";
        
        $params = array($product_id);
        $conditions = array();
        
        foreach ($attributes as $attribute_id => $value) {
            $conditions[] = "(va.attribute_id = %d AND va.attribute_value = %s)";
            $params[] = $attribute_id;
            $params[] = $value;
        }
        
        if (!empty($conditions)) {
            $query .= " AND " . implode(" AND ", $conditions);
        }
        
        $query .= " GROUP BY v.variant_id HAVING COUNT(va.id) = %d";
        $params[] = count($attributes);
        
        return $wpdb->get_var($wpdb->prepare($query, $params));
    }
}

设计要点二:构建高效的前端交互界面

动态属性选择器的实现

前端交互是多属性变体系统的用户体验核心。用户选择不同属性时,系统需要实时更新可用选项、价格、库存和产品图片。

// 动态属性选择器示例(基于jQuery)
class VariantSelector {
    constructor(productId, containerSelector) {
        this.productId = productId;
        this.container = $(containerSelector);
        this.selectedAttributes = {};
        this.availableVariants = {};
        this.init();
    }
    
    init() {
        // 获取产品变体数据
        this.fetchVariants();
        
        // 绑定属性选择事件
        this.container.on('change', '.attribute-option', (e) => {
            this.handleAttributeChange(e.target);
        });
    }
    
    async fetchVariants() {
        try {
            const response = await $.ajax({
                url: '/wp-json/custom-api/v1/products/' + this.productId + '/variants',
                method: 'GET'
            });
            
            this.availableVariants = response.variants;
            this.updateAttributeOptions();
        } catch (error) {
            console.error('Failed to fetch variants:', error);
        }
    }
    
    handleAttributeChange(selectElement) {
        const attributeId = $(selectElement).data('attribute-id');
        const value = $(selectElement).val();
        
        // 更新已选属性
        if (value) {
            this.selectedAttributes[attributeId] = value;
        } else {
            delete this.selectedAttributes[attributeId];
        }
        
        // 查找匹配的变体
        const matchedVariant = this.findMatchingVariant();
        
        // 更新UI
        this.updateUI(matchedVariant);
    }
    
    findMatchingVariant() {
        return Object.values(this.availableVariants).find(variant => {
            return this.areAttributesMatching(variant.attributes);
        });
    }
    
    areAttributesMatching(variantAttributes) {
        // 检查变体属性是否与已选属性匹配
        for (const [attrId, value] of Object.entries(this.selectedAttributes)) {
            if (!variantAttributes[attrId] || variantAttributes[attrId] !== value) {
                return false;
            }
        }
        return true;
    }
    
    updateUI(variant) {
        if (variant) {
            // 更新价格
            this.updatePrice(variant.price);
            
            // 更新库存状态
            this.updateStock(variant.stock_status, variant.stock_quantity);
            
            // 更新图片
            this.updateImage(variant.image_url);
            
            // 启用添加到购物车按钮
            this.enableAddToCart(true, variant.variant_id);
        } else {
            // 没有匹配变体,禁用添加到购物车
            this.enableAddToCart(false);
        }
        
        // 更新其他属性的可用选项
        this.updateAttributeOptions();
    }
}

响应式变体展示优化

在移动设备上,属性选择器的布局需要特别优化。我们可以采用以下策略:

  1. 折叠式选择器:在移动端将属性选择器折叠,点击展开
  2. 滑动选择:对于颜色等可视化属性,使用滑动选择器
  3. 图片预览:实时显示选中属性组合的产品图片
  4. 渐进式加载:先加载关键属性,其他属性按需加载
/* 响应式变体选择器CSS示例 */
.variant-selector {
    margin: 20px 0;
}

.attribute-group {
    margin-bottom: 15px;
}

.attribute-label {
    display: block;
    margin-bottom: 8px;
    font-weight: 600;
}

.attribute-options {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.attribute-option {
    padding: 8px 16px;
    border: 2px solid #ddd;
    border-radius: 4px;
    background: white;
    cursor: pointer;
    transition: all 0.2s;
}

.attribute-option.selected {
    border-color: #007cba;
    background-color: #f0f8ff;
}

.attribute-option.disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* 移动端优化 */
@media (max-width: 768px) {
    .attribute-options {
        overflow-x: auto;
        flex-wrap: nowrap;
        padding-bottom: 10px;
    }
    
    .attribute-option {
        flex-shrink: 0;
        min-width: 60px;
        text-align: center;
    }
    
    .variant-image-preview {
        position: sticky;
        top: 0;
        background: white;
        z-index: 10;
    }
}

设计要点三:设计高性能的后端API接口

RESTful API设计原则

为多属性变体系统设计API时,应遵循RESTful原则,确保接口的一致性和可预测性。

// WordPress REST API端点示例
class Product_Variants_REST_Controller extends WP_REST_Controller {
    
    public function register_routes() {
        // 获取产品变体列表
        register_rest_route('custom-api/v1', '/products/(?P<id>[d]+)/variants', array(
            array(
                'methods' => WP_REST_Server::READABLE,
                'callback' => array($this, 'get_product_variants'),
                'permission_callback' => array($this, 'get_items_permissions_check'),
                'args' => array(
                    'id' => array(
                        'validate_callback' => function($param, $request, $key) {
                            return is_numeric($param);
                        }
                    ),
                ),
            ),
            array(
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => array($this, 'create_product_variant'),
                'permission_callback' => array($this, 'create_item_permissions_check'),
            ),
        ));
        
        // 获取单个变体
        register_rest_route('custom-api/v1', '/variants/(?P<id>[d]+)', array(
            array(
                'methods' => WP_REST_Server::READABLE,
                'callback' => array($this, 'get_variant'),
                'permission_callback' => array($this, 'get_item_permissions_check'),
            ),
        ));
    }
    
    public function get_product_variants($request) {
        $product_id = $request->get_param('id');
        
        // 验证产品是否存在
        if (!get_post($product_id) || get_post_type($product_id) !== 'product') {
            return new WP_Error('rest_product_invalid', __('Invalid product ID.'), array('status' => 404));
        }
        
        // 获取变体数据
        $variants = $this->fetch_variants($product_id);
        
        // 格式化响应数据
        $response_data = array(
            'product_id' => $product_id,
            'variants' => $variants,
            'attributes' => $this->get_product_attributes($product_id),
            'total' => count($variants)
        );
        
        return rest_ensure_response($response_data);
    }
    
    private function fetch_variants($product_id) {
        global $wpdb;
        
        // 使用单个查询获取所有变体数据,避免N+1查询问题
        $query = $wpdb->prepare("
            SELECT 
                v.variant_id,
                v.sku,
                v.price,
                v.sale_price,
                v.stock_quantity,
                v.stock_status,
                v.image_id,
                GROUP_CONCAT(
                    CONCAT(a.attribute_slug, ':', va.attribute_value)
                    ORDER BY a.attribute_order
                    SEPARATOR '|'
                ) as attribute_string
            FROM {$wpdb->prefix}product_variants v
            LEFT JOIN {$wpdb->prefix}variant_attributes va ON v.variant_id = va.variant_id
            LEFT JOIN {$wpdb->prefix}custom_attributes a ON va.attribute_id = a.attribute_id
            WHERE v.product_id = %d AND v.status = 'publish'
            GROUP BY v.variant_id
            ORDER BY v.menu_order
        ", $product_id);
        
        $results = $wpdb->get_results($query);
        
        $variants = array();
        foreach ($results as $row) {
            $attributes = array();
            if ($row->attribute_string) {
                $pairs = explode('|', $row->attribute_string);
                foreach ($pairs as $pair) {
                    list($slug, $value) = explode(':', $pair, 2);
                    $attributes[$slug] = $value;
                }
            }
            
            $variants[] = array(
                'id' => (int)$row->variant_id,
                'sku' => $row->sku,
                'price' => (float)$row->price,
                'sale_price' => $row->sale_price ? (float)$row->sale_price : null,
                'stock_quantity' => (int)$row->stock_quantity,
                'stock_status' => $row->stock_status,
                'image_url' => $row->image_id ? wp_get_attachment_url($row->image_id) : null,
                'attributes' => $attributes
            );
        }
        
        return $variants;
    }
}

缓存策略优化

多属性变体接口可能面临高并发访问,合理的缓存策略至关重要。

// 变体数据缓存实现示例
class Variant_Cache_Manager {
    
    private $cache_group = 'product_variants';
    private $cache_expiration = 3600; // 1小时
    
    public function get_variants($product_id) {
        $cache_key = $this->get_cache_key($product_id);
        $cached = wp_cache_get($cache_key, $this->cache_group);
        
        if ($cached !== false) {
            return $cached;
        }
        
        // 从数据库获取数据
        $variants = $this->fetch_variants_from_db($product_id);
        
        // 设置缓存
        wp_cache_set($cache_key, $variants, $this->cache_group, $this->cache_expiration);
        
        return $variants;
    }
    
    public function invalidate_variant_cache($product_id) {
        $cache_key = $this->get_cache_key($product_id);
        wp_cache_delete($cache_key, $this->cache_group);
        
        // 同时清除相关产品的缓存
        $this->clear_related_caches($product_id);
    }
    
    private function get_cache_key($product_id) {
        return 'variants_' . $product_id . '_' . get_current_blog_id();
    }
    
    private function clear_related_caches($product_id) {
        // 清除产品列表页缓存
        wp_cache_delete('product_list_' . get_current_blog_id(), 'products');
        
        // 清除分类页面缓存
        $terms = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'ids'));
        foreach ($terms as $term_id) {
            wp_cache_delete('category_products_' . $term_id, 'products');
        }
    }
}

// 在适当的地方触发缓存清除
add_action('save_post_product', function($post_id, $post, $update) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    
    if ($post->post_type !== 'product') {
        return;
    }
    
    $cache_manager = new Variant_Cache_Manager();
    $cache_manager->invalidate_variant_cache($post_id);
}, 10, 3);

设计要点四:确保数据一致性与完整性

数据库事务处理

在多属性变体系统中,创建或更新变体通常涉及多个数据库操作,使用事务可以确保数据的一致性。

// 使用数据库事务创建变体
class Variant_Manager {
    
    public function create_variant($product_id, $variant_data) {
        global $wpdb;
        
        // 验证输入数据
        $validation_result = $this->validate_variant_data($variant_data);
        if (is_wp_error($validation_result)) {
            return $validation_result;
        }
        
        // 开始事务
        $wpdb->query('START TRANSACTION');
        
        try {
            // 插入变体基本信息
            $variant_insert = $wpdb->insert(
                $wpdb->prefix . 'product_variants',
                array(
                    'product_id' => $product_id,
                    'sku' => $variant_data['sku'],
                    'price' => $variant_data['price'],
                    'sale_price' => isset($variant_data['sale_price']) ? $variant_data['sale_price'] : null,
                    'stock_quantity' => $variant_data['stock_quantity'],
                    'stock_status' => $variant_data['stock_status'],
                    'menu_order' => isset($variant_data['menu_order']) ? $variant_data['menu_order'] : 0,
                    'status' => 'publish',
                    'created_at' => current_time('mysql'),
                    'updated_at' => current_time('mysql')
                ),
                array('%d', '%s', '%f', '%f', '%d', '%s', '%d', '%s', '%s', '%s')
            );
            
            if ($variant_insert === false) {
                throw new Exception('Failed to insert variant');
            }
            
            $variant_id = $wpdb->insert_id;
            
            // 插入变体属性关联
            if (!empty($variant_data['attributes'])) {
                foreach ($variant_data['attributes'] as $attribute_id => $attribute_value) {
                    $attribute_insert = $wpdb->insert(
                        $wpdb->prefix . 'variant_attributes',
                        array(
                            'variant_id' => $variant_id,
                            'attribute_id' => $attribute_id,
                            'attribute_value' => $attribute_value,
                            'created_at' => current_time('mysql')
                        ),
                        array('%d', '%d', '%s', '%s')
                    );
                    

if ($attribute_insert === false) {

                    throw new Exception('Failed to insert variant attribute');
                }
            }
        }
        
        // 处理变体图片
        if (!empty($variant_data['image_id'])) {
            $image_insert = $wpdb->insert(
                $wpdb->prefix . 'variant_images',
                array(
                    'variant_id' => $variant_id,
                    'image_id' => $variant_data['image_id'],
                    'is_primary' => 1,
                    'created_at' => current_time('mysql')
                ),
                array('%d', '%d', '%d', '%s')
            );
            
            if ($image_insert === false) {
                throw new Exception('Failed to insert variant image');
            }
        }
        
        // 提交事务
        $wpdb->query('COMMIT');
        
        // 清除缓存
        $cache_manager = new Variant_Cache_Manager();
        $cache_manager->invalidate_variant_cache($product_id);
        
        return $variant_id;
        
    } catch (Exception $e) {
        // 回滚事务
        $wpdb->query('ROLLBACK');
        
        error_log('Variant creation failed: ' . $e->getMessage());
        
        return new WP_Error(
            'variant_creation_failed',
            __('Failed to create variant: ', 'your-text-domain') . $e->getMessage(),
            array('status' => 500)
        );
    }
}

private function validate_variant_data($variant_data) {
    $required_fields = array('sku', 'price', 'stock_quantity', 'stock_status');
    
    foreach ($required_fields as $field) {
        if (!isset($variant_data[$field]) || empty($variant_data[$field])) {
            return new WP_Error(
                'missing_required_field',
                sprintf(__('Missing required field: %s', 'your-text-domain'), $field),
                array('status' => 400)
            );
        }
    }
    
    // 验证SKU唯一性
    if ($this->is_sku_exists($variant_data['sku'])) {
        return new WP_Error(
            'duplicate_sku',
            __('SKU already exists', 'your-text-domain'),
            array('status' => 400)
        );
    }
    
    // 验证价格有效性
    if (!is_numeric($variant_data['price']) || $variant_data['price'] < 0) {
        return new WP_Error(
            'invalid_price',
            __('Invalid price value', 'your-text-domain'),
            array('status' => 400)
        );
    }
    
    return true;
}

private function is_sku_exists($sku, $exclude_variant_id = 0) {
    global $wpdb;
    
    $query = $wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}product_variants WHERE sku = %s AND variant_id != %d",
        $sku,
        $exclude_variant_id
    );
    
    return $wpdb->get_var($query) > 0;
}

}


### 数据完整性约束

在数据库层面设置完整性约束,防止无效数据进入系统:

-- 数据库完整性约束示例
ALTER TABLE wp_product_variants
ADD CONSTRAINT fk_product_variants_product
FOREIGN KEY (product_id)
REFERENCES wp_posts(ID)
ON DELETE CASCADE
ON UPDATE CASCADE;

ALTER TABLE wp_variant_attributes
ADD CONSTRAINT fk_variant_attributes_variant
FOREIGN KEY (variant_id)
REFERENCES wp_product_variants(variant_id)
ON DELETE CASCADE
ON UPDATE CASCADE;

ALTER TABLE wp_variant_attributes
ADD CONSTRAINT fk_variant_attributes_attribute
FOREIGN KEY (attribute_id)
REFERENCES wp_custom_attributes(attribute_id)
ON DELETE CASCADE
ON UPDATE CASCADE;

-- 添加唯一约束,防止重复的属性组合
ALTER TABLE wp_variant_attributes
ADD UNIQUE INDEX idx_unique_variant_attribute (variant_id, attribute_id);

-- 添加检查约束(如果MySQL版本支持)
-- ALTER TABLE wp_product_variants
-- ADD CONSTRAINT chk_price_positive CHECK (price >= 0);


## 设计要点五:实现可扩展的架构设计

### 插件化架构设计

将多属性变体系统设计为可插拔的模块,便于功能扩展和维护:

// 主插件类 - 遵循WordPress插件标准
class WC_Product_Variants_Extension {


private static $instance = null;
private $modules = array();

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct() {
    $this->define_constants();
    $this->init_hooks();
    $this->load_modules();
}

private function define_constants() {
    define('WC_PVE_VERSION', '1.0.0');
    define('WC_PVE_PLUGIN_DIR', plugin_dir_path(__FILE__));
    define('WC_PVE_PLUGIN_URL', plugin_dir_url(__FILE__));
}

private function init_hooks() {
    // 初始化钩子
    add_action('init', array($this, 'init'));
    add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
    
    // 产品类型注册
    add_filter('product_type_selector', array($this, 'add_product_type'));
    
    // REST API初始化
    add_action('rest_api_init', array($this, 'register_rest_routes'));
}

private function load_modules() {
    // 自动加载模块
    $modules_dir = WC_PVE_PLUGIN_DIR . 'modules/';
    
    $module_files = array(
        'attribute-manager.php',
        'variant-manager.php',
        'inventory-manager.php',
        'pricing-manager.php',
        'import-export.php'
    );
    
    foreach ($module_files as $file) {
        $file_path = $modules_dir . $file;
        if (file_exists($file_path)) {
            require_once $file_path;
            
            $module_class = $this->get_module_class_name($file);
            if (class_exists($module_class)) {
                $this->modules[$module_class] = new $module_class();
            }
        }
    }
}

private function get_module_class_name($filename) {
    $name = str_replace(array('class-', '.php'), '', $filename);
    $name = str_replace('-', ' ', $name);
    $name = ucwords($name);
    $name = str_replace(' ', '_', $name);
    return $name . '_Module';
}

public function init() {
    // 初始化文本域
    load_plugin_textdomain('wc-product-variants', false, dirname(plugin_basename(__FILE__)) . '/languages');
    
    // 注册自定义数据库表
    $this->register_tables();
}

private function register_tables() {
    global $wpdb;
    
    $wpdb->product_variants = $wpdb->prefix . 'product_variants';
    $wpdb->variant_attributes = $wpdb->prefix . 'variant_attributes';
    $wpdb->custom_attributes = $wpdb->prefix . 'custom_attributes';
    
    // 创建或更新数据库表
    $this->create_tables();
}

private function create_tables() {
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    
    $charset_collate = $wpdb->get_charset_collate();
    
    // 创建产品变体表
    $sql = "CREATE TABLE IF NOT EXISTS {$wpdb->product_variants} (
        variant_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        product_id BIGINT UNSIGNED NOT NULL,
        sku VARCHAR(100) NOT NULL,
        price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
        sale_price DECIMAL(10,2) NULL,
        stock_quantity INT DEFAULT 0,
        stock_status VARCHAR(20) DEFAULT 'instock',
        image_id BIGINT UNSIGNED NULL,
        menu_order INT DEFAULT 0,
        status VARCHAR(20) DEFAULT 'publish',
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (variant_id),
        UNIQUE KEY sku (sku),
        KEY product_id (product_id),
        KEY status (status),
        KEY stock_status (stock_status)
    ) {$charset_collate};";
    
    dbDelta($sql);
    
    // 创建其他表...
}

}

// 初始化插件
function wc_product_variants_extension() {

return WC_Product_Variants_Extension::get_instance();

}

// 尽早初始化,但要在plugins_loaded之后
add_action('plugins_loaded', 'wc_product_variants_extension');


### 钩子与过滤器系统

提供丰富的钩子和过滤器,允许其他开发者扩展功能:

// 钩子系统实现
class Variant_Hooks_Manager {


public function __construct() {
    $this->register_core_hooks();
}

private function register_core_hooks() {
    // 变体保存前的钩子
    add_action('wc_variant_before_save', array($this, 'before_variant_save'), 10, 2);
    
    // 变体保存后的钩子
    add_action('wc_variant_after_save', array($this, 'after_variant_save'), 10, 2);
    
    // 变体价格计算过滤器
    add_filter('wc_variant_calculated_price', array($this, 'filter_variant_price'), 10, 3);
    
    // 变体库存检查过滤器
    add_filter('wc_variant_check_stock', array($this, 'filter_stock_check'), 10, 2);
    
    // 变体属性显示过滤器
    add_filter('wc_variant_display_attributes', array($this, 'filter_display_attributes'), 10, 2);
}

public function before_variant_save($variant_data, $variant_id) {
    // 允许其他插件修改变体数据
    $variant_data = apply_filters('wc_variant_pre_save_data', $variant_data, $variant_id);
    
    // 验证数据
    $validation = apply_filters('wc_variant_validation', true, $variant_data, $variant_id);
    
    if (is_wp_error($validation)) {
        return $validation;
    }
    
    return $variant_data;
}

public function after_variant_save($variant_id, $variant_data) {
    // 触发其他操作
    do_action('wc_variant_saved', $variant_id, $variant_data);
    
    // 记录日志
    do_action('wc_variant_save_log', $variant_id, $variant_data);
    
    // 发送通知
    do_action('wc_variant_save_notification', $variant_id, $variant_data);
}

public function filter_variant_price($price, $variant_id, $context) {
    // 允许其他插件修改价格计算逻辑
    $price = apply_filters('wc_variant_base_price', $price, $variant_id, $context);
    
    // 应用折扣
    $price = apply_filters('wc_variant_apply_discounts', $price, $variant_id, $context);
    
    // 应用税费
    $price = apply_filters('wc_variant_apply_taxes', $price, $variant_id, $context);
    
    return $price;
}

public function filter_stock_check($is_in_stock, $variant_id) {
    // 允许其他插件修改库存检查逻辑
    $is_in_stock = apply_filters('wc_variant_stock_status', $is_in_stock, $variant_id);
    
    // 检查预售状态
    $is_in_stock = apply_filters('wc_variant_preorder_status', $is_in_stock, $variant_id);
    
    return $is_in_stock;
}

public function filter_display_attributes($attributes, $variant_id) {
    // 允许格式化属性显示
    $attributes = apply_filters('wc_variant_format_attributes', $attributes, $variant_id);
    
    // 添加自定义属性显示
    $attributes = apply_filters('wc_variant_custom_attributes', $attributes, $variant_id);
    
    return $attributes;
}

}

// 扩展点示例 - 自定义价格计算
add_filter('wc_variant_base_price', function($price, $variant_id, $context) {

// 如果是批发用户,应用批发价格
if ($context === 'wholesale' && current_user_can('wholesale_customer')) {
    $wholesale_price = get_post_meta($variant_id, '_wholesale_price', true);
    if ($wholesale_price) {
        return $wholesale_price;
    }
}

return $price;

}, 10, 3);

// 扩展点示例 - 自定义库存管理
add_filter('wc_variant_stock_status', function($is_in_stock, $variant_id) {

// 检查是否允许备货
$allow_backorder = get_post_meta($variant_id, '_allow_backorder', true);

if ($allow_backorder === 'yes') {
    return true; // 允许备货,始终显示有货
}

return $is_in_stock;

}, 10, 2);


### 模块化扩展系统

设计模块化系统,便于添加新功能而不影响核心代码:

// 基础模块抽象类
abstract class WC_Variant_Module {


protected $module_id;
protected $module_name;
protected $module_description;
protected $module_version;

abstract public function init();

abstract public function register_hooks();

public function __construct() {
    $this->init();
    $this->register_hooks();
}

public function get_module_info() {
    return array(
        'id' => $this->module_id,
        'name' => $this->module_name,
        'description' => $this->module_description,
        'version' => $this->module_version
    );
}

}

// 具体模块实现 - 批量编辑模块
class Batch_Edit_Module extends WC_Variant_Module {


public function __construct() {
    $this->module_id = 'batch_edit';
    $this->module_name = __('Batch Edit Variants', 'wc-product-variants');
    $this->module_description = __('Batch edit product variants', 'wc-product-variants');
    $this->module_version = '1.0.0';
    
    parent::__construct();
}

public function init() {
    // 初始化模块
    $this->register_admin_pages();
}

public function register_hooks() {
    // 注册管理页面
    add_action('admin_menu', array($this, 'add_admin_menu'));
    
    // 注册AJAX处理
    add_action('wp_ajax_wc_variant_batch_edit', array($this, 'handle_batch_edit'));
    
    // 添加批量操作
    add_filter('bulk_actions-edit-product', array($this, 'add_bulk_actions'));
    add_filter('handle_bulk_actions-edit-product', array($this, 'handle_bulk_actions'), 10, 3);
}

private function register_admin_pages() {
    // 注册管理页面
    $this->admin_pages = array(
        'batch-edit' => array(
            'title' => __('Batch Edit Variants', 'wc-product-variants'),
            'capability' => 'manage_woocommerce',
            'callback' => array($this, 'render_batch_edit_page')
        )
    );
}

public function add_admin_menu() {
    add_submenu_page(
        'edit.php?post_type=product',
        __('Batch Edit Variants', 'wc-product-variants'),
        __('Batch Edit', 'wc-product-variants'),
        'manage_woocommerce',
        'wc-variant-batch-edit',
        array($this, 'render_batch_edit_page')
    );
}

public function render_batch_edit_page() {
    // 渲染批量编辑页面
    include WC_PVE_PLUGIN_DIR . 'templates/admin/batch-edit.php';
}

public function handle_batch_edit() {
    // 处理批量编辑请求
    check_ajax_referer('wc_variant_batch_edit', 'nonce');
    
    if (!current_user_can('manage_woocommerce')) {
        wp_die(-1);
    }
    
    $action = $_POST['action_type'] ?? '';
    $variant_ids = $_POST['variant_ids'] ?? array();
    $update_data = $_POST['update_data'] ?? array();
    
    switch ($action) {
        case 'update_prices':
            $result = $this->batch_update_prices($variant_ids, $update_data);
            break;
            
        case 'update_stock':
            $result = $this->batch_update_stock($variant_ids, $update_data);
            break;
            
        case 'update_attributes':
            $result = $this->batch_update_attributes($variant_ids, $update_data);
            break;
            
        default:
            $result = new WP_Error('invalid_action', __('Invalid action', 'wc-product-variants'));
    }
    
    if (is_wp_error($result)) {
        wp_send_json_error($result->get_error_message());
    } else {
        wp_send_json_success(array(
            'message' => __('Batch update completed successfully', 'wc-product-variants'),
            'updated_count' => count($variant_ids)
        ));
    }
}

private function batch_update_prices($variant_ids, $update_data) {
    global $wpdb;
    
    $updates = array();
    $formats = array();
    
    if (isset($update_data['price'])) {
        $updates['price'] = floatval($update_data['price']);
        $formats[] = '%f';
    }
    
    if (isset($update_data['sale_price'])) {
        $updates['sale_price'] = floatval($update_data['sale_price']);
        $formats[] = '%f';
   
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/268.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部