首页 / 教程文章 / 开发WordPress文创产品柔性预售系统教程

开发WordPress文创产品柔性预售系统教程

开发WordPress文创产品柔性预售系统教程

一、系统概述与需求分析

文创产品柔性预售系统是一种基于WordPress的电子商务解决方案,专门针对文创产品的预售特点设计。与传统电商系统不同,柔性预售系统需要处理以下特殊需求:

  1. 预售周期管理:支持设置预售开始和结束时间
  2. 生产数量弹性:根据预售数量动态调整生产计划
  3. 进度可视化:向客户展示预售进度和生产状态
  4. 灵活支付:支持定金+尾款或全款支付模式
  5. 限时优惠:预售期间的特殊定价策略

本教程将引导您从零开始开发一个完整的WordPress文创产品柔性预售系统。

二、环境搭建与基础配置

2.1 环境要求

  • WordPress 5.8+
  • PHP 7.4+
  • MySQL 5.6+
  • WooCommerce插件(作为电商基础)

2.2 安装必要插件

首先安装并激活以下插件:

  • WooCommerce(基础电商功能)
  • Advanced Custom Fields(自定义字段管理)

2.3 创建自定义插件

在wp-content/plugins目录下创建新文件夹flexible-presale-system,并在其中创建主文件:

<?php
/**
 * Plugin Name: 文创产品柔性预售系统
 * Plugin URI: https://yourwebsite.com/
 * Description: 专为文创产品设计的柔性预售管理系统
 * Version: 1.0.0
 * Author: 您的名称
 * License: GPL v2 or later
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('FPS_VERSION', '1.0.0');
define('FPS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FPS_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
add_action('plugins_loaded', 'fps_init');

function fps_init() {
    // 检查WooCommerce是否激活
    if (!class_exists('WooCommerce')) {
        add_action('admin_notices', function() {
            echo '<div class="error"><p>柔性预售系统需要WooCommerce插件,请先安装并激活WooCommerce。</p></div>';
        });
        return;
    }
    
    // 加载核心功能
    require_once FPS_PLUGIN_DIR . 'includes/class-presale-product.php';
    require_once FPS_PLUGIN_DIR . 'includes/class-presale-order.php';
    require_once FPS_PLUGIN_DIR . 'includes/class-presale-admin.php';
    
    // 初始化各个模块
    FPS_Presale_Product::init();
    FPS_Presale_Order::init();
    FPS_Presale_Admin::init();
    
    // 加载文本域
    load_plugin_textdomain('flexible-presale', false, dirname(plugin_basename(__FILE__)) . '/languages');
}

三、预售产品数据模型设计

3.1 创建自定义产品类型

includes/class-presale-product.php中添加预售产品类型:

class FPS_Presale_Product {
    
    public static function init() {
        add_action('init', array(__CLASS__, 'register_presale_product_type'));
        add_filter('product_type_selector', array(__CLASS__, 'add_presale_product_type'));
        add_action('woocommerce_product_options_general_product_data', array(__CLASS__, 'add_presale_product_fields'));
        add_action('woocommerce_process_product_meta', array(__CLASS__, 'save_presale_product_fields'));
    }
    
    // 注册预售产品类型
    public static function register_presale_product_type() {
        class WC_Product_Presale extends WC_Product_Simple {
            public function __construct($product) {
                parent::__construct($product);
                $this->product_type = 'presale';
            }
            
            public function get_type() {
                return 'presale';
            }
        }
    }
    
    // 在产品类型选择器中添加预售选项
    public static function add_presale_product_type($types) {
        $types['presale'] = __('文创预售产品', 'flexible-presale');
        return $types;
    }
    
    // 添加预售专属字段
    public static function add_presale_product_fields() {
        global $post;
        
        echo '<div class="options_group presale_options show_if_presale">';
        
        // 预售开始时间
        woocommerce_wp_text_input(array(
            'id' => '_presale_start_date',
            'label' => __('预售开始时间', 'flexible-presale'),
            'placeholder' => 'YYYY-MM-DD HH:MM',
            'description' => __('设置预售开始的具体时间', 'flexible-presale'),
            'type' => 'datetime-local'
        ));
        
        // 预售结束时间
        woocommerce_wp_text_input(array(
            'id' => '_presale_end_date',
            'label' => __('预售结束时间', 'flexible-presale'),
            'placeholder' => 'YYYY-MM-DD HH:MM',
            'description' => __('设置预售结束的具体时间', 'flexible-presale'),
            'type' => 'datetime-local'
        ));
        
        // 最低起订量
        woocommerce_wp_text_input(array(
            'id' => '_presale_min_quantity',
            'label' => __('最低起订量', 'flexible-presale'),
            'description' => __('达到此数量才会进入生产阶段', 'flexible-presale'),
            'type' => 'number',
            'custom_attributes' => array(
                'step' => '1',
                'min' => '1'
            )
        ));
        
        // 预售价格
        woocommerce_wp_text_input(array(
            'id' => '_presale_price',
            'label' => __('预售价格', 'flexible-presale') . ' (' . get_woocommerce_currency_symbol() . ')',
            'description' => __('预售期间的优惠价格', 'flexible-presale'),
            'type' => 'number',
            'custom_attributes' => array(
                'step' => '0.01',
                'min' => '0'
            )
        ));
        
        echo '</div>';
        
        // 添加JavaScript控制产品类型显示
        ?>
        <script>
        jQuery(document).ready(function($) {
            // 显示/隐藏预售选项
            $('select#product-type').change(function() {
                if ($(this).val() === 'presale') {
                    $('.presale_options').show();
                } else {
                    $('.presale_options').hide();
                }
            }).trigger('change');
        });
        </script>
        <?php
    }
    
    // 保存预售产品字段
    public static function save_presale_product_fields($post_id) {
        $product = wc_get_product($post_id);
        
        if ($product->get_type() === 'presale') {
            // 保存预售开始时间
            if (isset($_POST['_presale_start_date'])) {
                $product->update_meta_data('_presale_start_date', sanitize_text_field($_POST['_presale_start_date']));
            }
            
            // 保存预售结束时间
            if (isset($_POST['_presale_end_date'])) {
                $product->update_meta_data('_presale_end_date', sanitize_text_field($_POST['_presale_end_date']));
            }
            
            // 保存最低起订量
            if (isset($_POST['_presale_min_quantity'])) {
                $product->update_meta_data('_presale_min_quantity', absint($_POST['_presale_min_quantity']));
            }
            
            // 保存预售价格
            if (isset($_POST['_presale_price'])) {
                $product->update_meta_data('_presale_price', wc_format_decimal($_POST['_presale_price']));
                // 同时更新常规价格
                $product->set_price(wc_format_decimal($_POST['_presale_price']));
                $product->set_regular_price(wc_format_decimal($_POST['_presale_price']));
            }
            
            $product->save();
        }
    }
}

四、预售订单处理逻辑

4.1 订单状态管理

创建includes/class-presale-order.php文件处理预售订单:

class FPS_Presale_Order {
    
    public static function init() {
        // 注册自定义订单状态
        add_action('init', array(__CLASS__, 'register_presale_order_statuses'));
        add_filter('wc_order_statuses', array(__CLASS__, 'add_presale_order_statuses'));
        
        // 预售产品添加到购物车时的验证
        add_filter('woocommerce_add_to_cart_validation', array(__CLASS__, 'validate_presale_product'), 10, 3);
        
        // 修改预售产品价格显示
        add_filter('woocommerce_get_price_html', array(__CLASS__, 'display_presale_price'), 10, 2);
        
        // 检查预售状态
        add_action('template_redirect', array(__CLASS__, 'check_presale_availability'));
    }
    
    // 注册预售专属订单状态
    public static function register_presale_order_statuses() {
        register_post_status('wc-presale-pending', array(
            'label' => __('等待生产', 'flexible-presale'),
            'public' => true,
            'exclude_from_search' => false,
            'show_in_admin_all_list' => true,
            'show_in_admin_status_list' => true,
            'label_count' => _n_noop('等待生产 <span class="count">(%s)</span>', '等待生产 <span class="count">(%s)</span>', 'flexible-presale')
        ));
        
        register_post_status('wc-presale-in-production', array(
            'label' => __('生产中', 'flexible-presale'),
            'public' => true,
            'exclude_from_search' => false,
            'show_in_admin_all_list' => true,
            'show_in_admin_status_list' => true,
            'label_count' => _n_noop('生产中 <span class="count">(%s)</span>', '生产中 <span class="count">(%s)</span>', 'flexible-presale')
        ));
    }
    
    // 将预售状态添加到订单状态列表
    public static function add_presale_order_statuses($order_statuses) {
        $order_statuses['wc-presale-pending'] = __('等待生产', 'flexible-presale');
        $order_statuses['wc-presale-in-production'] = __('生产中', 'flexible-presale');
        return $order_statuses;
    }
    
    // 验证预售产品是否可以购买
    public static function validate_presale_product($passed, $product_id, $quantity) {
        $product = wc_get_product($product_id);
        
        if ($product->get_type() === 'presale') {
            $current_time = current_time('timestamp');
            $start_date = strtotime($product->get_meta('_presale_start_date'));
            $end_date = strtotime($product->get_meta('_presale_end_date'));
            
            // 检查是否在预售期内
            if ($current_time < $start_date) {
                wc_add_notice(__('该产品预售尚未开始', 'flexible-presale'), 'error');
                return false;
            }
            
            if ($current_time > $end_date) {
                wc_add_notice(__('该产品预售已结束', 'flexible-presale'), 'error');
                return false;
            }
            
            // 检查库存限制
            $min_quantity = $product->get_meta('_presale_min_quantity');
            $sold_quantity = self::get_presale_sold_quantity($product_id);
            
            if (($sold_quantity + $quantity) > $min_quantity * 3) { // 假设最大预售量为最低起订量的3倍
                wc_add_notice(sprintf(__('该产品预售数量已达上限,最多还可购买%d件', 'flexible-presale'), 
                    max(0, $min_quantity * 3 - $sold_quantity)), 'error');
                return false;
            }
        }
        
        return $passed;
    }
    
    // 获取已售预售数量
    private static function get_presale_sold_quantity($product_id) {
        global $wpdb;
        
        $query = "
            SELECT SUM(oi.meta_value) as total_sold
            FROM {$wpdb->prefix}woocommerce_order_itemmeta oim
            JOIN {$wpdb->prefix}woocommerce_order_items oi ON oim.order_item_id = oi.order_item_id
            JOIN {$wpdb->prefix}posts p ON oi.order_id = p.ID
            WHERE oim.meta_key = '_product_id'
            AND oim.meta_value = %d
            AND p.post_status IN ('wc-processing', 'wc-completed', 'wc-presale-pending', 'wc-presale-in-production')
        ";
        
        $result = $wpdb->get_var($wpdb->prepare($query, $product_id));
        
        return $result ? intval($result) : 0;
    }
    
    // 显示预售价格和进度
    public static function display_presale_price($price, $product) {
        if ($product->get_type() === 'presale') {
            $original_price = $product->get_meta('_original_price');
            $presale_price = $product->get_meta('_presale_price');
            $min_quantity = $product->get_meta('_presale_min_quantity');
            $sold_quantity = self::get_presale_sold_quantity($product->get_id());
            
            $progress_percentage = min(100, ($sold_quantity / $min_quantity) * 100);
            
            $price_html = '<div class="presale-price-info">';
            $price_html .= '<span class="presale-price">' . wc_price($presale_price) . '</span>';
            
            if ($original_price && $original_price > $presale_price) {
                $price_html .= '<del class="original-price">' . wc_price($original_price) . '</del>';
            }
            
            $price_html .= '<div class="presale-progress">';
            $price_html .= '<div class="progress-bar"><div class="progress-fill" style="width:' . $progress_percentage . '%"></div></div>';
            $price_html .= '<span class="progress-text">' . 
                sprintf(__('已预售 %d/%d 件 (%.1f%%)', 'flexible-presale'), 
                    $sold_quantity, $min_quantity, $progress_percentage) . 
                '</span>';
            $price_html .= '</div></div>';
            
            return $price_html;
        }
        
        return $price;
    }
    
    // 检查预售产品可用性
    public static function check_presale_availability() {
        if (is_product()) {
            global $post;
            $product = wc_get_product($post->ID);
            
            if ($product->get_type() === 'presale') {
                $current_time = current_time('timestamp');
                $start_date = strtotime($product->get_meta('_presale_start_date'));
                $end_date = strtotime($product->get_meta('_presale_end_date'));
                
                // 如果预售已结束,重定向到产品存档页面
                if ($current_time > $end_date) {
                    wp_redirect(get_permalink(wc_get_page_id('shop')));
                    exit;
                }
            }
        }
    }
}

五、后台管理界面开发

5.1 预售数据统计面板

创建includes/class-presale-admin.php文件:

class FPS_Presale_Admin {
    
    public static function init() {
        // 添加预售统计菜单
        add_action('admin_menu', array(__CLASS__, 'add_admin_menu'));
        
        // 在产品列表添加预售状态列
        add_filter('manage_product_posts_columns', array(__CLASS__, 'add_presale_status_column'));
        add_action('manage_product_posts_custom_column', array(__CLASS__, 'display_presale_status_column'), 10, 2);
        
        // 添加批量操作
        add_filter('bulk_actions-edit-product', array(__CLASS__, 'add_presale_bulk_actions'));
        add_filter('handle_bulk_actions-edit-product', array(__CLASS__, 'handle_presale_bulk_actions'), 10, 3);
    }
    
    // 添加管理菜单
    public static function add_admin_menu() {
        add_submenu_page(
            'woocommerce',
            __('预售数据统计', 'flexible-presale'),
            __('预售统计', 'flexible-presale'),
            'manage_woocommerce',
            'presale-statistics',
            array(__CLASS__, 'display_statistics_page')
        );
    }
    
    // 显示统计页面
    public static function display_statistics_page() {
        ?>
        <div class="wrap">
            <h1><?php _e('文创产品预售统计', 'flexible-presale'); ?></h1>
            
            <div class="presale-stats-container">
                <div class="stats-overview">
                    <div class="stat-box">
                        <h3><?php _e('进行中的预售', 'flexible-presale'); ?></h3>
                        <span class="stat-number"><?php echo self::get_active_presale_count(); ?></span>
                    </div>
                    
                    <div class="stat-box">
                        <h3><?php _e('总预售金额', 'flexible-presale'); ?></h3>
                        <span class="stat-number"><?php echo wc_price(self::get_total_presale_revenue()); ?></span>
                    </div>
                    
                    <div class="stat-box">
                        <h3><?php _e('平均达成率', 'flexible-presale'); ?></h3>
                        <span class="stat-number"><?php echo self::get_average_completion_rate(); ?>%</span>
                    </div>
                </div>
                
                <div class="presale-list">
                    <h2><?php _e('预售产品详情', 'flexible-presale'); ?></h2>
                    <table class="wp-list-table widefat fixed striped">
                        <thead>
                            <tr>

flexible-presale'); ?></th>

                            <th><?php _e('预售进度', 'flexible-presale'); ?></th>
                            <th><?php _e('剩余时间', 'flexible-presale'); ?></th>
                            <th><?php _e('预售金额', 'flexible-presale'); ?></th>
                            <th><?php _e('操作', 'flexible-presale'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php echo self::get_presale_products_list(); ?>
                    </tbody>
                </table>
            </div>
        </div>
        
        <style>
            .presale-stats-container { margin-top: 20px; }
            .stats-overview { display: flex; gap: 20px; margin-bottom: 30px; }
            .stat-box { 
                flex: 1; 
                background: #fff; 
                padding: 20px; 
                border-radius: 5px; 
                box-shadow: 0 2px 5px rgba(0,0,0,0.1);
                text-align: center;
            }
            .stat-number { 
                font-size: 32px; 
                font-weight: bold; 
                color: #0073aa; 
                display: block;
                margin-top: 10px;
            }
            .progress-cell { min-width: 200px; }
            .progress-bar { 
                height: 20px; 
                background: #f0f0f0; 
                border-radius: 10px; 
                overflow: hidden;
                margin-bottom: 5px;
            }
            .progress-fill { 
                height: 100%; 
                background: #46b450; 
                transition: width 0.3s;
            }
        </style>
    </div>
    <?php
}

// 获取活跃预售产品数量
private static function get_active_presale_count() {
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => '_presale_end_date',
                'value' => current_time('mysql'),
                'compare' => '>',
                'type' => 'DATETIME'
            )
        )
    );
    
    $query = new WP_Query($args);
    return $query->found_posts;
}

// 在产品列表添加预售状态列
public static function add_presale_status_column($columns) {
    $new_columns = array();
    
    foreach ($columns as $key => $value) {
        $new_columns[$key] = $value;
        if ($key === 'name') {
            $new_columns['presale_status'] = __('预售状态', 'flexible-presale');
        }
    }
    
    return $new_columns;
}

// 显示预售状态列内容
public static function display_presale_status_column($column, $post_id) {
    if ($column === 'presale_status') {
        $product = wc_get_product($post_id);
        
        if ($product->get_type() === 'presale') {
            $current_time = current_time('timestamp');
            $start_date = strtotime($product->get_meta('_presale_start_date'));
            $end_date = strtotime($product->get_meta('_presale_end_date'));
            
            if ($current_time < $start_date) {
                echo '<span class="presale-status upcoming">' . __('即将开始', 'flexible-presale') . '</span>';
            } elseif ($current_time <= $end_date) {
                $min_quantity = $product->get_meta('_presale_min_quantity');
                $sold_quantity = FPS_Presale_Order::get_presale_sold_quantity($post_id);
                $percentage = min(100, ($sold_quantity / $min_quantity) * 100);
                
                echo '<div class="progress-cell">';
                echo '<div class="progress-bar"><div class="progress-fill" style="width:' . $percentage . '%"></div></div>';
                echo '<span>' . sprintf(__('%d/%d (%.1f%%)', 'flexible-presale'), $sold_quantity, $min_quantity, $percentage) . '</span>';
                echo '</div>';
            } else {
                echo '<span class="presale-status ended">' . __('已结束', 'flexible-presale') . '</span>';
            }
        }
    }
}

}


## 六、前端展示与用户交互

### 6.1 预售产品页面模板
在插件目录下创建`templates/single-product-presale.php`:

<?php
/**

  • 预售产品页面模板
    */

defined('ABSPATH') || exit;

global $product;

// 获取预售信息
$presale_start = $product->get_meta('_presale_start_date');
$presale_end = $product->get_meta('_presale_end_date');
$min_quantity = $product->get_meta('_presale_min_quantity');
$sold_quantity = FPS_Presale_Order::get_presale_sold_quantity($product->get_id());

// 计算剩余时间
$current_time = current_time('timestamp');
$end_time = strtotime($presale_end);
$time_left = $end_time - $current_time;

// 计算进度百分比
$progress_percentage = min(100, ($sold_quantity / $min_quantity) * 100);

// 计算剩余天数
$days_left = floor($time_left / (60 60 24));
$hours_left = floor(($time_left % (60 60 24)) / (60 * 60));
?>

<div class="presale-product-wrapper">


<!-- 预售状态横幅 -->
<div class="presale-banner">
    <div class="banner-content">
        <span class="presale-badge"><?php _e('文创预售', 'flexible-presale'); ?></span>
        <div class="countdown-timer">
            <span class="timer-label"><?php _e('剩余时间:', 'flexible-presale'); ?></span>
            <span class="timer-value"><?php printf(__('%d天%d小时', 'flexible-presale'), $days_left, $hours_left); ?></span>
        </div>
    </div>
</div>

<!-- 预售进度条 -->
<div class="presale-progress-section">
    <div class="progress-header">
        <span class="progress-title"><?php _e('预售进度', 'flexible-presale'); ?></span>
        <span class="progress-numbers"><?php printf(__('%d/%d 件', 'flexible-presale'), $sold_quantity, $min_quantity); ?></span>
    </div>
    <div class="progress-bar-container">
        <div class="progress-bar">
            <div class="progress-fill" style="width: <?php echo $progress_percentage; ?>%"></div>
        </div>
        <div class="progress-labels">
            <span class="progress-min"><?php _e('起订量', 'flexible-presale'); ?></span>
            <span class="progress-max"><?php _e('目标', 'flexible-presale'); ?></span>
        </div>
    </div>
    
    <?php if ($progress_percentage >= 100): ?>
        <div class="progress-success">
            <span class="success-icon">✓</span>
            <span class="success-text"><?php _e('已达成预售目标,即将进入生产阶段!', 'flexible-presale'); ?></span>
        </div>
    <?php elseif ($progress_percentage >= 70): ?>
        <div class="progress-warning">
            <span class="warning-text"><?php _e('预售即将达成,剩余数量有限!', 'flexible-presale'); ?></span>
        </div>
    <?php endif; ?>
</div>

<!-- 预售说明 -->
<div class="presale-notice">
    <h3><?php _e('预售说明', 'flexible-presale'); ?></h3>
    <ul class="presale-features">
        <li><?php _e('• 预售期间享受优惠价格', 'flexible-presale'); ?></li>
        <li><?php _e('• 达到起订量后开始生产', 'flexible-presale'); ?></li>
        <li><?php _e('• 生产完成后按订单顺序发货', 'flexible-presale'); ?></li>
        <li><?php _e('• 预售结束后恢复原价', 'flexible-presale'); ?></li>
        <li><?php _e('• 支持预售期间无理由退款', 'flexible-presale'); ?></li>
    </ul>
</div>

<!-- 生产时间线 -->
<div class="production-timeline">
    <h3><?php _e('预计时间线', 'flexible-presale'); ?></h3>
    <div class="timeline-steps">
        <div class="timeline-step <?php echo $progress_percentage >= 100 ? 'active' : ''; ?>">
            <div class="step-number">1</div>
            <div class="step-content">
                <h4><?php _e('预售阶段', 'flexible-presale'); ?></h4>
                <p><?php echo date('Y-m-d', strtotime($presale_start)); ?> - <?php echo date('Y-m-d', strtotime($presale_end)); ?></p>
            </div>
        </div>
        <div class="timeline-step">
            <div class="step-number">2</div>
            <div class="step-content">
                <h4><?php _e('生产阶段', 'flexible-presale'); ?></h4>
                <p><?php _e('预售结束后30天内', 'flexible-presale'); ?></p>
            </div>
        </div>
        <div class="timeline-step">
            <div class="step-number">3</div>
            <div class="step-content">
                <h4><?php _e('发货阶段', 'flexible-presale'); ?></h4>
                <p><?php _e('生产完成后7个工作日内', 'flexible-presale'); ?></p>
            </div>
        </div>
    </div>
</div>

</div>

<style>
.presale-product-wrapper { margin: 20px 0; }
.presale-banner {

background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px 20px;
border-radius: 8px;
margin-bottom: 20px;

}
.presale-badge {

background: rgba(255,255,255,0.2);
padding: 5px 15px;
border-radius: 20px;
font-weight: bold;

}
.countdown-timer {

float: right;
font-size: 1.1em;

}
.presale-progress-section {

background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;

}
.progress-header {

display: flex;
justify-content: space-between;
margin-bottom: 15px;

}
.progress-bar-container {

position: relative;

}
.progress-bar {

height: 30px;
background: #e9ecef;
border-radius: 15px;
overflow: hidden;

}
.progress-fill {

height: 100%;
background: linear-gradient(90deg, #4cd964, #5ac8fa);
transition: width 0.5s ease;

}
.progress-labels {

display: flex;
justify-content: space-between;
margin-top: 5px;
font-size: 0.9em;
color: #6c757d;

}
.production-timeline {

margin-top: 30px;

}
.timeline-steps {

display: flex;
justify-content: space-between;
position: relative;

}
.timeline-steps:before {

content: '';
position: absolute;
top: 25px;
left: 10%;
right: 10%;
height: 2px;
background: #dee2e6;
z-index: 1;

}
.timeline-step {

flex: 1;
text-align: center;
position: relative;
z-index: 2;

}
.step-number {

width: 50px;
height: 50px;
background: #e9ecef;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 10px;
font-weight: bold;
font-size: 1.2em;

}
.timeline-step.active .step-number {

background: #007bff;
color: white;

}
</style>


### 6.2 注册模板文件
在插件主文件中添加模板加载功能:

// 在fps_init函数中添加
add_filter('woocommerce_locate_template', 'fps_locate_template', 10, 3);

function fps_locate_template($template, $template_name, $template_path) {

// 如果是预售产品模板
if ($template_name === 'single-product-presale.php') {
    $plugin_template = FPS_PLUGIN_DIR . 'templates/' . $template_name;
    if (file_exists($plugin_template)) {
        return $plugin_template;
    }
}
return $template;

}

// 设置预售产品使用自定义模板
add_filter('template_include', 'fps_product_template', 99);

function fps_product_template($template) {

if (is_singular('product')) {
    global $post;
    $product = wc_get_product($post->ID);
    
    if ($product->get_type() === 'presale') {
        $new_template = FPS_PLUGIN_DIR . 'templates/single-product-presale.php';
        if (file_exists($new_template)) {
            return $new_template;
        }
    }
}
return $template;

}


## 七、系统测试与优化

### 7.1 创建测试数据
在插件中创建测试功能:

// 创建测试预售产品
function fps_create_test_presale_product() {

$product = new WC_Product_Presale();
$product->set_name('测试文创产品 - 限量版艺术画册');
$product->set_status('publish');
$product->set_catalog_visibility('visible');
$product->set_description('这是一本精美的限量版艺术画册,收录了多位艺术家的代表作。');
$product->set_short_description('限量预售,仅此一批');
$product->set_price(199);
$product->set_regular_price(299);

// 设置预售元数据
$product->update_meta_data('_presale_start_date', date('Y-m-d H:i:s', strtotime('-1 day')));
$product->update_meta_data('_presale_end_date', date('Y-m-d H:i:s', strtotime('+30 days')));
$product->update_meta_data('_presale_min_quantity', 100);
$product->update_meta_data('_presale_price', 199);
$product->update_meta_data('_original_price', 299);

$product->save();

// 设置产品图片
$image_url = 'https://via.placeholder.com/800x800/667eea/ffffff?text=文创产品';
$image_id = fps_upload_image_from_url($image_url);
if ($image_id) {
    $product->set_image_id($image_id);
    $product->save();
}

return $product->get_id();

}

// 从URL上传图片
function fps_upload_image_from_url($image_url) {

require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');

$tmp = download_url($image_url);
if (is_wp_error($tmp)) {
    return false;
}

$file_array = array(
    'name' => basename($image_url),
    'tmp_name' => $tmp
);

$id = media_handle_sideload($file_array, 0);

if (is_wp_error($id)) {
    @unlink($file_array['tmp_name']);
    return false;
}

return $id;

}


### 7.2 性能优化建议

1. **数据库优化**:
   - 为预售产品添加索引
   - 定期清理过期预售数据
   - 使用缓存减少查询次数

2. **前端优化**:
   - 使用AJAX加载预售进度
   - 实现倒计时客户端计算
   - 压缩CSS和JavaScript文件

3. **安全考虑**:
   - 验证所有用户输入
   - 使用nonce保护表单
   - 限制API访问频率

## 八、部署与维护

### 8.1 系统部署步骤

1. **环境检查**:

# 检查PHP版本
php -v

# 检查WordPress版本
wp core version

# 检查WooCommerce状态
wp plugin status woocommerce


2. **安装插件**:
- 将插件文件夹上传到wp-content/plugins/
- 在WordPress后台激活插件
- 运行数据库初始化脚本

3. **配置设置**:
- 设置预售产品默认选项
- 配置邮件通知模板
- 设置支付网关集成

### 8.2 日常维护任务

1. **监控预售进度**:
- 每日检查预售数据
- 监控库存和订单状态
- 及时处理异常订单

2. **数据备份**:

// 创建预售数据备份函数
function fps_backup_presale_data() {

   global $wpdb;
   
   $backup_data = array(
       'timestamp' => current_time('mysql'),
       'presale_products' => $wpdb->get_results("
           SELECT p.ID, p.post_title, 
                  pm1.meta_value as presale_end
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5791.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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