首页 / 教程文章 / WordPress小批量定制插件支持客户协同设计的教程

WordPress小批量定制插件支持客户协同设计的教程

WordPress小批量定制插件支持客户协同设计的教程

引言:为什么需要客户协同设计插件

在WordPress网站开发中,经常会遇到需要为客户定制功能的情况。传统的开发模式往往是单向的:客户提出需求→开发者实现→客户验收。这种模式存在沟通成本高、需求理解偏差、反复修改等问题。通过开发一个支持客户协同设计的插件,我们可以让客户在开发过程中直接参与界面设计和功能配置,大大提高开发效率和客户满意度。

本教程将指导您创建一个完整的WordPress插件,支持小批量定制和客户协同设计功能。我们将构建一个简单的产品配置器作为示例,客户可以通过它自定义产品选项并实时预览效果。

插件基础结构

首先,我们需要创建插件的基本文件结构:

<?php
/**
 * Plugin Name: 客户协同设计工具
 * Plugin URI: https://yourwebsite.com/
 * Description: 支持客户参与设计过程的小批量定制插件
 * Version: 1.0.0
 * Author: 您的名字
 * License: GPL v2 or later
 */

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

// 定义插件常量
define('CCD_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('CCD_PLUGIN_URL', plugin_dir_url(__FILE__));
define('CCD_VERSION', '1.0.0');

// 初始化插件
class ClientCoDesignPlugin {
    
    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() {
        // 后台初始化
        add_action('admin_init', array($this, 'admin_init'));
        
        // 添加管理菜单
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // 前端资源加载
        add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
        
        // 后台资源加载
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
        
        // 注册短代码
        add_shortcode('product_configurator', array($this, 'render_configurator'));
        
        // AJAX处理
        add_action('wp_ajax_save_design', array($this, 'save_design_callback'));
        add_action('wp_ajax_nopriv_save_design', array($this, 'save_design_callback'));
    }
    
    // 后续方法将在这里添加
}

// 启动插件
ClientCoDesignPlugin::get_instance();
?>

数据库设计与数据管理

协同设计插件需要存储客户的设计选择和配置。我们将创建一个自定义数据库表来存储这些信息:

// 在ClientCoDesignPlugin类中添加以下方法

/**
 * 创建必要的数据库表
 */
public function create_database_tables() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'client_designs';
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        user_id mediumint(9) NOT NULL,
        project_name varchar(100) NOT NULL,
        design_data longtext NOT NULL,
        status varchar(20) DEFAULT 'draft',
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY user_id (user_id),
        KEY status (status)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

/**
 * 激活插件时创建表
 */
public static function activate_plugin() {
    $plugin = new self();
    $plugin->create_database_tables();
    
    // 创建默认选项
    add_option('ccd_default_options', array(
        'max_designs_per_user' => 10,
        'allow_guest_designs' => true,
        'default_product_types' => array('T恤', '杯子', '海报')
    ));
}

/**
 * 保存设计数据
 */
public function save_design($user_id, $project_name, $design_data) {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'client_designs';
    
    // 检查用户是否超过最大设计数量限制
    $max_designs = get_option('ccd_default_options')['max_designs_per_user'];
    $user_design_count = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT COUNT(*) FROM $table_name WHERE user_id = %d",
            $user_id
        )
    );
    
    if ($user_design_count >= $max_designs) {
        return new WP_Error('limit_exceeded', '已达到最大设计数量限制');
    }
    
    // 插入或更新设计数据
    $result = $wpdb->replace(
        $table_name,
        array(
            'user_id' => $user_id,
            'project_name' => $project_name,
            'design_data' => json_encode($design_data),
            'status' => 'draft'
        ),
        array('%d', '%s', '%s', '%s')
    );
    
    return $result ? $wpdb->insert_id : false;
}

前端配置器界面

创建一个直观的前端界面,让客户可以实时配置产品:

/**
 * 渲染产品配置器短代码
 */
public function render_configurator($atts) {
    // 解析短代码属性
    $atts = shortcode_atts(array(
        'product_type' => 'tshirt',
        'show_preview' => 'true'
    ), $atts, 'product_configurator');
    
    // 获取当前用户ID(访客为0)
    $user_id = is_user_logged_in() ? get_current_user_id() : 0;
    
    // 生成唯一会话ID用于访客
    if ($user_id === 0) {
        if (!isset($_SESSION['guest_session_id'])) {
            $_SESSION['guest_session_id'] = 'guest_' . wp_generate_uuid4();
        }
        $session_id = $_SESSION['guest_session_id'];
    }
    
    ob_start();
    ?>
    <div class="ccd-configurator-container" data-user-id="<?php echo esc_attr($user_id); ?>" data-product-type="<?php echo esc_attr($atts['product_type']); ?>">
        
        <div class="ccd-header">
            <h2>产品定制设计器</h2>
            <p>实时调整选项,右侧预览将立即更新</p>
        </div>
        
        <div class="ccd-main-content">
            <!-- 左侧配置面板 -->
            <div class="ccd-control-panel">
                <div class="ccd-section">
                    <h3>1. 基本设置</h3>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-product-color">产品颜色:</label>
                        <select id="ccd-product-color" class="ccd-control" data-target="preview-color">
                            <option value="#FF0000">红色</option>
                            <option value="#00FF00" selected>绿色</option>
                            <option value="#0000FF">蓝色</option>
                            <option value="#FFFF00">黄色</option>
                            <option value="#FFFFFF">白色</option>
                        </select>
                    </div>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-product-size">产品尺寸:</label>
                        <select id="ccd-product-size" class="ccd-control" data-target="preview-size">
                            <option value="S">小号 (S)</option>
                            <option value="M" selected>中号 (M)</option>
                            <option value="L">大号 (L)</option>
                            <option value="XL">加大 (XL)</option>
                        </select>
                    </div>
                </div>
                
                <div class="ccd-section">
                    <h3>2. 自定义文本</h3>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-custom-text">文本内容:</label>
                        <input type="text" id="ccd-custom-text" class="ccd-control" 
                               data-target="preview-text" 
                               placeholder="输入自定义文本" 
                               maxlength="50">
                    </div>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-text-color">文本颜色:</label>
                        <input type="color" id="ccd-text-color" class="ccd-control" 
                               data-target="preview-text-color" 
                               value="#000000">
                    </div>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-text-size">文本大小:</label>
                        <input type="range" id="ccd-text-size" class="ccd-control" 
                               data-target="preview-text-size" 
                               min="12" max="72" value="24">
                        <span class="ccd-range-value">24px</span>
                    </div>
                </div>
                
                <div class="ccd-section">
                    <h3>3. 上传图案</h3>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-upload-image">上传图片:</label>
                        <input type="file" id="ccd-upload-image" class="ccd-control" 
                               accept="image/*" style="display: none;">
                        <button type="button" id="ccd-upload-button" class="ccd-button">选择图片</button>
                        <div id="ccd-image-preview" class="ccd-image-preview"></div>
                    </div>
                    
                    <div class="ccd-control-group">
                        <label for="ccd-image-opacity">图案透明度:</label>
                        <input type="range" id="ccd-image-opacity" class="ccd-control" 
                               data-target="preview-image-opacity" 
                               min="0" max="100" value="100">
                        <span class="ccd-range-value">100%</span>
                    </div>
                </div>
                
                <!-- 保存和分享按钮 -->
                <div class="ccd-actions">
                    <button type="button" id="ccd-save-design" class="ccd-button ccd-button-primary">
                        <span class="dashicons dashicons-saved"></span> 保存设计
                    </button>
                    <button type="button" id="ccd-share-design" class="ccd-button ccd-button-secondary">
                        <span class="dashicons dashicons-share"></span> 分享设计
                    </button>
                    <button type="button" id="ccd-reset-design" class="ccd-button">
                        <span class="dashicons dashicons-update"></span> 重置
                    </button>
                </div>
            </div>
            
            <!-- 右侧实时预览 -->
            <div class="ccd-preview-panel">
                <h3>实时预览</h3>
                <div class="ccd-preview-container">
                    <div class="ccd-product-preview" id="ccd-product-preview">
                        <!-- 预览内容将通过JavaScript动态更新 -->
                        <div class="ccd-product-base" id="ccd-product-base">
                            <div class="ccd-product-text" id="ccd-product-text">示例文本</div>
                            <div class="ccd-product-image" id="ccd-product-image"></div>
                        </div>
                    </div>
                </div>
                
                <div class="ccd-preview-info">
                    <h4>设计摘要</h4>
                    <ul id="ccd-design-summary">
                        <li>颜色: <span id="summary-color">绿色</span></li>
                        <li>尺寸: <span id="summary-size">中号 (M)</span></li>
                        <li>自定义文本: <span id="summary-text">无</span></li>
                    </ul>
                </div>
            </div>
        </div>
        
        <!-- 设计保存表单 -->
        <div class="ccd-save-modal" id="ccd-save-modal" style="display: none;">
            <div class="ccd-modal-content">
                <h3>保存您的设计</h3>
                <form id="ccd-save-form">
                    <div class="ccd-form-group">
                        <label for="ccd-design-name">设计名称:</label>
                        <input type="text" id="ccd-design-name" required 
                               placeholder="例如: 公司周年纪念T恤">
                    </div>
                    
                    <div class="ccd-form-group">
                        <label for="ccd-design-notes">设计备注:</label>
                        <textarea id="ccd-design-notes" rows="3" 
                                  placeholder="添加一些备注或说明..."></textarea>
                    </div>
                    
                    <div class="ccd-form-actions">
                        <button type="submit" class="ccd-button ccd-button-primary">保存设计</button>
                        <button type="button" id="ccd-cancel-save" class="ccd-button">取消</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <?php
    
    return ob_get_clean();
}

JavaScript交互与实时预览

添加JavaScript代码以实现实时预览和AJAX交互:

// 创建文件 /assets/js/ccd-frontend.js
jQuery(document).ready(function($) {
    'use strict';
    
    // 设计配置对象
    var designConfig = {
        color: '#00FF00',
        size: 'M',
        text: '',
        textColor: '#000000',
        textSize: 24,
        image: null,
        imageOpacity: 100
    };
    
    // 初始化配置器
    function initConfigurator() {
        // 绑定控制事件
        $('.ccd-control').on('change input', handleControlChange);
        
        // 初始化颜色选择器
        $('#ccd-text-color').on('change', updateTextColor);
        
        // 初始化范围输入
        $('input[type="range"]').on('input', function() {
            $(this).next('.ccd-range-value').text($(this).val() + 
                ($(this).attr('id') === 'ccd-text-size' ? 'px' : '%'));
        });
        
        // 图片上传
        $('#ccd-upload-button').on('click', function() {
            $('#ccd-upload-image').click();
        });
        
        $('#ccd-upload-image').on('change', handleImageUpload);
        
        // 按钮事件
        $('#ccd-save-design').on('click', openSaveModal);
        $('#ccd-share-design').on('click', shareDesign);
        $('#ccd-reset-design').on('click', resetDesign);
        $('#ccd-cancel-save').on('click', closeSaveModal);
        
        // 保存表单提交
        $('#ccd-save-form').on('submit', saveDesign);
        
        // 初始更新预览
        updatePreview();
        updateSummary();
    }
    
    // 处理控制变化
    function handleControlChange(e) {
        var $control = $(this);
        var controlId = $control.attr('id');
        var value = $control.val();
        var target = $control.data('target');
        
        // 更新设计配置
        switch(controlId) {
            case 'ccd-product-color':
                designConfig.color = value;
                break;
            case 'ccd-product-size':
                designConfig.size = value;
                break;
            case 'ccd-custom-text':
                designConfig.text = value;
                break;
            case 'ccd-text-size':
                designConfig.textSize = parseInt(value);
                break;
            case 'ccd-image-opacity':
                designConfig.imageOpacity = parseInt(value);
                break;
        }
        
        // 更新预览
        updatePreview();
        updateSummary();
    }
    
    // 更新文本颜色
    function updateTextColor() {
        designConfig.textColor = $(this).val();
        updatePreview();
    }
    
    // 处理图片上传
    function handleImageUpload(e) {
        var file = e.target.files[0];
        if (!file) return;
        
        // 验证文件类型
        if (!file.type.match('image.*')) {
            alert('请选择图片文件');
            return;
        }
        
        // 验证文件大小(最大2MB)
        if (file.size > 2 * 1024 * 1024) {
            alert('图片大小不能超过2MB');
            return;
        }
        
        // 创建预览
        var reader = new FileReader();
        reader.onload = function(e) {
            designConfig.image = e.target.result;
            $('#ccd-image-preview').html(
                '<img src="' + e.target.result + '" alt="上传的图片" style="max-width: 100px;">'
            );
            updatePreview();
        };
        reader.readAsDataURL(file);
    }
    
    // 更新预览
    function updatePreview() {
        // 更新产品基础颜色
        $('#ccd-product-base').css('background-color', designConfig.color);
        
        // 更新文本
        var $productText = $('#ccd-product-text');
        if (designConfig.text) {
            $productText.text(designConfig.text);
            $productText.show();
            $productText.css({
                'color': designConfig.textColor,
                'font-size': designConfig.textSize + 'px'
            });
        } else {
            $productText.hide();
        }
        
        // 更新图片
        var $productImage = $('#ccd-product-image');
        if (designConfig.image) {
            $productImage.html('<img src="' + designConfig.image + '" alt="设计图案">');
            $productImage.find('img').css('opacity', designConfig.imageOpacity / 100);
            $productImage.show();
        } else {
            $productImage.hide();
        }
    }
    
    // 更新设计摘要
    function updateSummary() {
        $('#summary-color').text(getColorName(designConfig.color));
        $('#summary-size').text(getSizeName(designConfig.size));
        $('#summary-text').text(designConfig.text || '无');
    }
    
    // 获取颜色名称
    function getColorName(hex) {
        var colors = {
            '#FF0000': '红色',
            '#00FF00': '绿色',
            '#0000FF': '蓝色',
            '#FFFF00': '黄色',
            '#FFFFFF': '白色'
        };
        return colors[hex] || hex;
    }
    
    // 获取尺寸名称
    function getSizeName(size) {
        var sizes = {
            'S': '小号 (S)',
            'M': '中号 (M)',
            'L': '大号 (L)',
            'XL': '加大 (XL)'
        };
        return sizes[size] || size;
    }
    
    // 打开保存模态框
    function openSaveModal() {
        $('#ccd-save-modal').fadeIn();
        $('#ccd-design-name').focus();
    }
    
    // 关闭保存模态框
    function closeSaveModal() {
        $('#ccd-save-modal').fadeOut();
        $('#ccd-save-form')[0].reset();
    }
    
    // 分享设计
    function shareDesign() {
        // 生成设计快照
        html2canvas(document.querySelector('#ccd-product-preview')).then(canvas => {
            var imageData = canvas.toDataURL('image/png');
            
            // 创建分享模态框
            var shareModal = $(
                '<div class="ccd-share-modal">' +
                '<div class="ccd-modal-content">' +
                '<h3>分享设计</h3>' +
                '<div class="ccd-share-image">' +
                '<img src="' + imageData + '" alt="设计预览">' +
                '</div>' +
                '<div class="ccd-share-options">' +
                '<button class="ccd-button" id="ccd-download-image">下载图片</button>' +
                '<button class="ccd-button" id="ccd-copy-link">复制分享链接</button>' +
                '<button class="ccd-button" id="ccd-close-share">关闭</button>' +
                '</div>' +
                '</div>' +
                '</div>'
            );
            
            $('body').append(shareModal);
            
            // 绑定分享按钮事件
            $('#ccd-download-image').on('click', function() {
                var link = document.createElement('a');
                link.download = '我的设计.png';
                link.href = imageData;
                link.click();
            });
            
            $('#ccd-copy-link').on('click', function() {
                // 在实际应用中,这里应该生成一个唯一的分享链接
                var shareUrl = window.location.href + '?design=' + btoa(JSON.stringify(designConfig));
                navigator.clipboard.writeText(shareUrl).then(function() {
                    alert('分享链接已复制到剪贴板!');
                });
            });
            
            $('#ccd-close-share').on('click', function() {
                shareModal.remove();
            });
        });
    }
    
    // 重置设计
    function resetDesign() {
        if (confirm('确定要重置所有设置吗?')) {
            designConfig = {
                color: '#00FF00',
                size: 'M',
                text: '',
                textColor: '#000000',
                textSize: 24,
                image: null,
                imageOpacity: 100
            };
            
            // 重置表单控件
            $('#ccd-product-color').val('#00FF00');
            $('#ccd-product-size').val('M');
            $('#ccd-custom-text').val('');
            $('#ccd-text-color').val('#000000');
            $('#ccd-text-size').val(24);
            $('#ccd-image-opacity').val(100);
            $('#ccd-upload-image').val('');
            $('#ccd-image-preview').empty();
            
            // 更新显示值
            $('.ccd-range-value').each(function() {
                var $input = $(this).prev('input');
                $(this).text($input.val() + ($input.attr('id') === 'ccd-text-size' ? 'px' : '%'));
            });
            
            updatePreview();
            updateSummary();
        }
    }
    
    // 保存设计到服务器
    function saveDesign(e) {
        e.preventDefault();
        
        var designName = $('#ccd-design-name').val();
        if (!designName.trim()) {
            alert('请输入设计名称');
            return;
        }
        
        var designNotes = $('#ccd-design-notes').val();
        var userId = $('.ccd-configurator-container').data('user-id');
        
        // 显示加载状态
        var $submitBtn = $(this).find('button[type="submit"]');
        var originalText = $submitBtn.text();
        $submitBtn.html('<span class="dashicons dashicons-update"></span> 保存中...').prop('disabled', true);
        
        // 准备设计数据
        var designData = {
            config: designConfig,
            name: designName,
            notes: designNotes,
            timestamp: new Date().toISOString(),
            preview: '' // 在实际应用中,这里可以添加base64编码的预览图
        };
        
        // 发送AJAX请求
        $.ajax({
            url: ccd_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'save_design',
                nonce: ccd_ajax.nonce,
                user_id: userId,
                design_name: designName,
                design_data: designData
            },
            success: function(response) {
                if (response.success) {
                    alert('设计保存成功!');
                    closeSaveModal();
                    
                    // 在实际应用中,这里可以重定向到设计管理页面
                    console.log('设计ID:', response.data.design_id);
                } else {
                    alert('保存失败: ' + response.data.message);
                }
            },
            error: function() {
                alert('网络错误,请稍后重试');
            },
            complete: function() {
                $submitBtn.text(originalText).prop('disabled', false);
            }
        });
    }
    
    // 初始化
    initConfigurator();
});

后台管理界面

创建后台管理界面,让开发者可以管理客户的设计和配置选项:

// 在ClientCoDesignPlugin类中添加以下方法

/**
 * 添加管理菜单
 */
public function add_admin_menu() {
    // 主菜单
    add_menu_page(
        '协同设计管理',
        '协同设计',
        'manage_options',
        'client-co-design',
        array($this, 'render_admin_dashboard'),
        'dashicons-art',
        30
    );
    
    // 子菜单
    add_submenu_page(
        'client-co-design',
        '设计管理',
        '设计管理',
        'manage_options',
        'ccd-designs',
        array($this, 'render_designs_page')
    );
    
    add_submenu_page(
        'client-co-design',
        '产品配置',
        '产品配置',
        'manage_options',
        'ccd-products',
        array($this, 'render_products_page')
    );
    
    add_submenu_page(
        'client-co-design',
        '设置',
        '设置',
        'manage_options',
        'ccd-settings',
        array($this, 'render_settings_page')
    );
}

/**
 * 渲染管理仪表板
 */
public function render_admin_dashboard() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'client_designs';
    
    // 获取统计数据
    $total_designs = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
    $active_designs = $wpdb->get_var(
        $wpdb->prepare("SELECT COUNT(*) FROM $table_name WHERE status = %s", 'active')
    );
    $recent_designs = $wpdb->get_results(
        "SELECT * FROM $table_name ORDER BY created_at DESC LIMIT 5"
    );
    
    ?>
    <div class="wrap ccd-admin-dashboard">
        <h1>协同设计管理仪表板</h1>
        
        <div class="ccd-stats-container">
            <div class="ccd-stat-card">
                <h3>总设计数</h3>
                <div class="ccd-stat-number"><?php echo esc_html($total_designs); ?></div>
            </div>
            
            <div class="ccd-stat-card">
                <h3>活跃设计</h3>
                <div class="ccd-stat-number"><?php echo esc_html($active_designs); ?></div>
            </div>
            
            <div class="ccd-stat-card">
                <h3>今日新增</h3>
                <div class="ccd-stat-number">
                    <?php 
                    $today = $wpdb->get_var(
                        $wpdb->prepare(
                            "SELECT COUNT(*) FROM $table_name WHERE DATE(created_at) = %s",
                            current_time('Y-m-d')
                        )
                    );
                    echo esc_html($today);
                    ?>
                </div>
            </div>
        </div>
        
        <div class="ccd-recent-designs">
            <h2>最近的设计</h2>
            
            <?php if ($recent_designs): ?>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>设计名称</th>
                            <th>用户</th>
                            <th>状态</th>
                            <th>创建时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($recent_designs as $design): 
                            $user_info = get_userdata($design->user_id);
                            $username = $user_info ? $user_info->display_name : '访客';
                        ?>
                        <tr>
                            <td><?php echo esc_html($design->id); ?></td>
                            <td><?php echo esc_html($design->project_name); ?></td>
                            <td><?php echo esc_html($username); ?></td>
                            <td>
                                <span class="ccd-status-badge ccd-status-<?php echo esc_attr($design->status); ?>">
                                    <?php 
                                    $status_labels = array(
                                        'draft' => '草稿',
                                        'active' => '活跃',
                                        'completed' => '完成'
                                    );
                                    echo esc_html($status_labels[$design->status] ?? $design->status);
                                    ?>
                                </span>
                            </td>
                            <td><?php echo esc_html(date('Y-m-d H:i', strtotime($design->created_at))); ?></td>
                            <td>
                                <button class="button button-small view-design" data-design-id="<?php echo esc_attr($design->id); ?>">
                                    查看
                                </button>
                                <button class="button button-small edit-design" data-design-id="<?php echo esc_attr($design->id); ?>">
                                    编辑
                                </button>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            <?php else: ?>
                <p>暂无设计数据。</p>
            <?php endif; ?>
        </div>
    </div>
    <?php
}

/**
 * 渲染设计管理页面
 */
public function render_designs_page() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'client_designs';
    $per_page = 20;
    $current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
    $offset = ($current_page - 1) * $per_page;
    
    // 获取筛选条件
    $status_filter = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : '';
    $search_term = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
    
    // 构建查询
    $where_clauses = array('1=1');
    $query_params = array();
    
    if ($status_filter) {
        $where_clauses[] = "status = %s";
        $query_params[] = $status_filter;
    }
    
    if ($search_term) {
        $where_clauses[] = "(project_name LIKE %s OR id = %s)";
        $query_params[] = '%' . $wpdb->esc_like($search_term) . '%';
        $query_params[] = $search_term;
    }
    
    $where_sql = implode(' AND ', $where_clauses);
    
    // 获取总记录数
    $count_query = "SELECT COUNT(*) FROM $table_name WHERE $where_sql";
    if ($query_params) {
        $count_query = $wpdb->prepare($count_query, $query_params);
    }
    $total_items = $wpdb->get_var($count_query);
    
    // 获取当前页数据
    $data_query = "SELECT * FROM $table_name WHERE $where_sql ORDER BY created_at DESC LIMIT %d OFFSET %d";
    $query_params[] = $per_page;
    $query_params[] = $offset;
    $data_query = $wpdb->prepare($data_query, $query_params);
    $designs = $wpdb->get_results($data_query);
    
    ?>
    <div class="wrap">
        <h1 class="wp-heading-inline">设计管理</h1>
        
        <form method="get" class="ccd-filter-form">
            <input type="hidden" name="page" value="ccd-designs">
            
            <div class="ccd-filters">
                <select name="status" class="ccd-filter-select">
                    <option value="">所有状态</option>
                    <option value="draft" <?php selected($status_filter, 'draft'); ?>>草稿</option>
                    <option value="active" <?php selected($status_filter, 'active'); ?>>活跃</option>
                    <option value="completed" <?php selected($status_filter, 'completed'); ?>>完成</option>
                </select>
                
                <input type="text" name="s" placeholder="搜索设计名称或ID" 
                       value="<?php echo esc_attr($search_term); ?>" class="ccd-search-input">
                
                <button type="submit" class="button">筛选</button>
                
                <?php if ($status_filter || $search_term): ?>
                    <a href="<?php echo admin_url('admin.php?page=ccd-designs'); ?>" class="button">
                        清除筛选
                    </a>
                <?php endif; ?>
            </div>
        </form>
        
        <div class="ccd-designs-list">
            <?php if ($designs): ?>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>设计名称</th>
                            <th>用户</th>
                            <th>状态</th>
                            <th>创建时间</th>
                            <th>更新时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($designs as $design): 
                            $user_info = get_userdata($design->user_id);
                            $username = $user_info ? $user_info->display_name : '访客';
                            $design_data = json_decode($design->design_data, true);
                        ?>
                        <tr>
                            <td><?php echo esc_html($design->id); ?></td>
                            <td>
                                <strong><?php echo esc_html($design->project_name); ?></strong>
                                <?php if (!empty($design_data['notes'])): ?>
                                    <br><small><?php echo esc_html(substr($design_data['notes'], 0, 50)); ?>...</small>
                                <?php endif; ?>
                            </td>
                            <td><?php echo esc_html($username); ?></td>
                            <td>
                                <select class="ccd-status-select" data-design-id="<?php echo esc_attr($design->id); ?>">
                                    <option value="draft" <?php selected($design->status, 'draft'); ?>>草稿</option>
                                    <option value="active" <?php selected($design->status, 'active'); ?>>活跃</option>
                                    <option value="completed" <?php selected($design->status, 'completed'); ?>>完成</option>
                                </select>
                            </td>
                            <td><?php echo esc_html(date('Y-m-d H:i', strtotime($design->created_at))); ?></td>
                            <td><?php echo esc_html(date('Y-m-d H:i', strtotime($design->updated_at))); ?></td>
                            <td>
                                <div class="ccd-action-buttons">
                                    <button class="button button-small ccd-view-design" 
                                            data-design-id="<?php echo esc_attr($design->id); ?>">
                                        查看详情
                                    </button>
                                    <button class="button button-small ccd-export-design" 
                                            data-design-id="<?php echo esc_attr($design->id); ?>">
                                        导出
                                    </button>
                                    <button class="button button-small ccd-delete-design" 
                                            data-design-id="<?php echo esc_attr($design->id); ?>"
                                            onclick="return confirm('确定要删除这个设计吗?')">
                                        删除
                                    </button>
                                </div>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                
                <!-- 分页 -->
                <div class="ccd-pagination">
                    <?php
                    $total_pages = ceil($total_items / $per_page);
                    $base_url = admin_url('admin.php?page=ccd-designs');
                    
                    if ($total_pages > 1) {
                        echo paginate_links(array(
                            'base' => add_query_arg('paged', '%#%', $base_url),
                            'format' => '',
                            'prev_text' => '&laquo;',
                            'next_text' => '&raquo;',
                            'total' => $total_pages,
                            'current' => $current_page,
                            'add_args' => array(
                                'status' => $status_filter,
                                's' => $search_term
                            )
                        ));
                    }
                    ?>
                </div>
            <?php else: ?>
                <p>没有找到匹配的设计。</p>
            <?php endif; ?>
        </div>
    </div>
    <?php
}

AJAX处理与数据保存

/**
 * 保存设计AJAX回调
 */
public function save_design_callback() {
    // 验证nonce
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5971.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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