首页 / 教程文章 / WordPress文创插件开发柔性产品配置器与可视化定制教程

WordPress文创插件开发柔性产品配置器与可视化定制教程

本文介绍了如何开发一个WordPress文创插件,以实现柔性产品配置器和可视化定制功能。随着文创产品定制化需求的增长,该插件帮助文化机构、博物馆及文创品牌在线提供个性化定制服务。教程涵盖插件架构设计、数据库表结构、产品配置器核心类、前端可视化编辑器及WordPress短代码集成等内容,指导读者逐步构建完整的文创产品在线定制系统,使用户能够自主设计并预览定制产品。

WordPress文创插件开发:柔性产品配置器与可视化定制教程

引言:文创产品定制化的市场需求

随着个性化消费时代的到来,文创产品的定制化需求日益增长。无论是文化机构、博物馆、艺术工作室还是文创品牌,都希望通过在线平台为客户提供个性化的产品定制服务。WordPress作为全球最流行的内容管理系统,为文创产品的在线定制提供了理想的平台基础。

本文将详细介绍如何开发一个WordPress文创插件,实现柔性产品配置器和可视化定制功能。通过本教程,您将学会创建一个完整的文创产品定制系统,让用户能够在线设计并预览自己的定制产品。

插件架构设计

1. 插件基础结构

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

wp-content/plugins/cultural-creator/
├── cultural-creator.php          # 主插件文件
├── includes/
│   ├── class-product-configurator.php
│   ├── class-visual-editor.php
│   ├── class-ajax-handler.php
│   └── class-database.php
├── assets/
│   ├── css/
│   ├── js/
│   └── images/
├── templates/
│   ├── configurator-frontend.php
│   └── admin-settings.php
└── languages/

2. 主插件文件初始化

<?php
/**
 * Plugin Name: 文创产品定制器
 * Plugin URI:  https://example.com/cultural-creator
 * Description: 为WordPress网站提供文创产品可视化定制功能
 * Version:     1.0.0
 * Author:      文创开发者
 * License:     GPL v2 or later
 * Text Domain: cultural-creator
 */

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

// 定义插件常量
define('CC_VERSION', '1.0.0');
define('CC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CC_PLUGIN_URL', plugin_dir_url(__FILE__));

// 自动加载类文件
spl_autoload_register(function ($class) {
    $prefix = 'CulturalCreator_';
    $base_dir = CC_PLUGIN_DIR . 'includes/';
    
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    
    $relative_class = substr($class, $len);
    $file = $base_dir . 'class-' . str_replace('_', '-', strtolower($relative_class)) . '.php';
    
    if (file_exists($file)) {
        require $file;
    }
});

// 初始化插件
function cultural_creator_init() {
    // 检查WordPress版本
    if (version_compare(get_bloginfo('version'), '5.0', '<')) {
        add_action('admin_notices', function() {
            echo '<div class="notice notice-error"><p>文创产品定制器需要WordPress 5.0或更高版本</p></div>';
        });
        return;
    }
    
    // 初始化核心类
    $configurator = new CulturalCreator_ProductConfigurator();
    $visual_editor = new CulturalCreator_VisualEditor();
    $ajax_handler = new CulturalCreator_AjaxHandler();
    
    // 注册激活和停用钩子
    register_activation_hook(__FILE__, ['CulturalCreator_Database', 'install_tables']);
    register_deactivation_hook(__FILE__, ['CulturalCreator_Database', 'deactivate']);
}
add_action('plugins_loaded', 'cultural_creator_init');

数据库设计与产品配置器

1. 数据库表结构

<?php
// includes/class-database.php

class CulturalCreator_Database {
    
    public static function install_tables() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        $table_prefix = $wpdb->prefix . 'cc_';
        
        // 产品表
        $products_table = $table_prefix . 'products';
        $sql_products = "CREATE TABLE IF NOT EXISTS $products_table (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            name varchar(255) NOT NULL,
            slug varchar(100) NOT NULL,
            base_price decimal(10,2) DEFAULT '0.00',
            base_image varchar(500),
            product_type varchar(50) DEFAULT 'mug',
            customizable_areas text,
            status tinyint(1) DEFAULT 1,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY slug (slug)
        ) $charset_collate;";
        
        // 设计元素表
        $elements_table = $table_prefix . 'design_elements';
        $sql_elements = "CREATE TABLE IF NOT EXISTS $elements_table (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            product_id mediumint(9) NOT NULL,
            element_type varchar(50) NOT NULL,
            element_name varchar(255) NOT NULL,
            element_data text,
            position_x int DEFAULT 0,
            position_y int DEFAULT 0,
            width int DEFAULT 100,
            height int DEFAULT 100,
            z_index int DEFAULT 1,
            is_locked tinyint(1) DEFAULT 0,
            PRIMARY KEY (id),
            KEY product_id (product_id)
        ) $charset_collate;";
        
        // 用户设计表
        $designs_table = $table_prefix . 'user_designs';
        $sql_designs = "CREATE TABLE IF NOT EXISTS $designs_table (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            user_id bigint(20) unsigned,
            session_id varchar(100),
            product_id mediumint(9) NOT NULL,
            design_data text NOT NULL,
            preview_image varchar(500),
            total_price decimal(10,2) DEFAULT '0.00',
            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 session_id (session_id),
            KEY product_id (product_id)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql_products);
        dbDelta($sql_elements);
        dbDelta($sql_designs);
    }
}

2. 产品配置器核心类

<?php
// includes/class-product-configurator.php

class CulturalCreator_ProductConfigurator {
    
    private $product_id;
    private $product_data;
    
    public function __construct($product_id = null) {
        if ($product_id) {
            $this->product_id = $product_id;
            $this->load_product_data();
        }
    }
    
    /**
     * 加载产品数据
     */
    private function load_product_data() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'cc_products';
        
        $this->product_data = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $this->product_id)
        );
    }
    
    /**
     * 获取可定制区域配置
     * @return array 可定制区域配置数组
     */
    public function get_customizable_areas() {
        if (!$this->product_data) {
            return [];
        }
        
        $areas = json_decode($this->product_data->customizable_areas, true);
        
        // 默认区域配置
        $default_areas = [
            'front' => [
                'name' => '正面',
                'width' => 400,
                'height' => 300,
                'position' => ['x' => 50, 'y' => 50],
                'allow_text' => true,
                'allow_image' => true,
                'allow_shape' => true
            ],
            'back' => [
                'name' => '背面',
                'width' => 400,
                'height' => 300,
                'position' => ['x' => 500, 'y' => 50],
                'allow_text' => true,
                'allow_image' => true,
                'allow_shape' => false
            ]
        ];
        
        return wp_parse_args($areas, $default_areas);
    }
    
    /**
     * 计算定制产品价格
     * @param array $design_elements 设计元素数组
     * @return float 总价格
     */
    public function calculate_price($design_elements) {
        $base_price = $this->product_data->base_price;
        $total_price = floatval($base_price);
        
        foreach ($design_elements as $element) {
            switch ($element['type']) {
                case 'text':
                    // 文字按长度和字体复杂度计价
                    $text_price = strlen($element['content']) * 0.1;
                    if (isset($element['font']) && $element['font'] !== 'default') {
                        $text_price += 2.0;
                    }
                    $total_price += $text_price;
                    break;
                    
                case 'image':
                    // 图片按尺寸和复杂度计价
                    $image_price = 5.0;
                    if (isset($element['width']) && $element['width'] > 200) {
                        $image_price += 3.0;
                    }
                    $total_price += $image_price;
                    break;
                    
                case 'shape':
                    // 图形按复杂度计价
                    $shape_price = 3.0;
                    if (isset($element['complexity']) && $element['complexity'] === 'high') {
                        $shape_price += 4.0;
                    }
                    $total_price += $shape_price;
                    break;
            }
        }
        
        return round($total_price, 2);
    }
}

可视化编辑器实现

1. 前端可视化编辑器

// assets/js/visual-editor.js

class CulturalCreatorVisualEditor {
    constructor(config) {
        this.config = config;
        this.canvas = null;
        this.ctx = null;
        this.elements = [];
        this.selectedElement = null;
        this.isDragging = false;
        this.dragOffset = { x: 0, y: 0 };
        
        this.init();
    }
    
    /**
     * 初始化编辑器
     */
    init() {
        this.createCanvas();
        this.loadProductTemplate();
        this.setupEventListeners();
        this.setupToolbar();
        this.render();
    }
    
    /**
     * 创建画布
     */
    createCanvas() {
        const container = document.getElementById(this.config.containerId);
        
        // 创建画布元素
        this.canvas = document.createElement('canvas');
        this.canvas.width = this.config.width || 800;
        this.canvas.height = this.config.height || 600;
        this.canvas.style.border = '1px solid #ddd';
        this.canvas.style.backgroundColor = '#f9f9f9';
        
        container.appendChild(this.canvas);
        this.ctx = this.canvas.getContext('2d');
    }
    
    /**
     * 加载产品模板
     */
    loadProductTemplate() {
        // 绘制产品基础轮廓
        this.ctx.fillStyle = '#ffffff';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 绘制可定制区域
        const areas = this.config.customizableAreas;
        Object.keys(areas).forEach(areaKey => {
            const area = areas[areaKey];
            
            // 绘制区域边界
            this.ctx.strokeStyle = '#4a90e2';
            this.ctx.lineWidth = 2;
            this.ctx.setLineDash([5, 5]);
            this.ctx.strokeRect(
                area.position.x,
                area.position.y,
                area.width,
                area.height
            );
            
            // 添加区域标签
            this.ctx.fillStyle = '#4a90e2';
            this.ctx.font = '14px Arial';
            this.ctx.fillText(
                area.name,
                area.position.x + 5,
                area.position.y - 5
            );
            
            this.ctx.setLineDash([]);
        });
    }
    
    /**
     * 添加文本元素
     * @param {Object} options 文本选项
     */
    addTextElement(options) {
        const defaultOptions = {
            id: 'text_' + Date.now(),
            content: '新文本',
            x: 100,
            y: 100,
            fontSize: 24,
            fontFamily: 'Arial',
            color: '#000000',
            area: 'front'
        };
        
        const textElement = { ...defaultOptions, ...options, type: 'text' };
        this.elements.push(textElement);
        this.render();
        
        return textElement.id;
    }
    
    /**
     * 添加图片元素
     * @param {Object} options 图片选项
     */
    addImageElement(options) {
        const img = new Image();
        img.crossOrigin = 'anonymous';
        
        img.onload = () => {
            const imageElement = {
                id: 'image_' + Date.now(),
                image: img,
                x: options.x || 150,
                y: options.y || 150,
                width: options.width || 100,
                height: options.height || 100,
                src: options.src,
                area: options.area || 'front',
                type: 'image'
            };
            
            this.elements.push(imageElement);
            this.render();
        };
        
        img.src = options.src;
    }
    
    /**
     * 渲染所有元素
     */
    render() {
        // 清除画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 重新绘制产品模板
        this.loadProductTemplate();
        
        // 绘制所有元素
        this.elements.forEach(element => {
            this.drawElement(element);
        });
        
        // 绘制选中元素的控制点
        if (this.selectedElement) {
            this.drawSelectionBox(this.selectedElement);
        }
    }
    
    /**
     * 绘制单个元素
     * @param {Object} element 元素对象
     */
    drawElement(element) {
        this.ctx.save();
        
        switch (element.type) {
            case 'text':
                this.ctx.font = `${element.fontSize}px ${element.fontFamily}`;
                this.ctx.fillStyle = element.color;
                this.ctx.fillText(element.content, element.x, element.y);
                break;
                
            case 'image':
                if (element.image && element.image.complete) {
                    this.ctx.drawImage(
                        element.image,
                        element.x,
                        element.y,
                        element.width,
                        element.height
                    );
                }
                break;
        }
        
        this.ctx.restore();
    }
    
    /**
     * 设置事件监听器
     */
    setupEventListeners() {
        this.canvas.addEventListener('mousedown', this.handleMouseDown.bind(this));
        this.canvas.addEventListener('mousemove', this.handleMouseMove.bind(this));
        this.canvas.addEventListener('mouseup', this.handleMouseUp.bind(this));
        this.canvas.addEventListener('click', this.handleClick.bind(this));
    }
    
    /**
     * 处理鼠标按下事件
     * @param {Event} e 鼠标事件
     */
    handleMouseDown(e) {
        const rect = this.canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        
        // 检查是否点击了元素
        for (let i = this.elements.length - 1; i >= 0; i--) {
            const element = this.elements[i];
            
            if (this.isPointInElement(x, y, element)) {
                this.selectedElement = element;
                this.isDragging = true;
                
                // 计算拖拽偏移量
                this.dragOffset.x = x - element.x;
                this.dragOffset.y = y - element.y;
                
                this.render();
                break;
            }
        }
    }
    
    /**
     * 检查点是否在元素内
     * @param {number} x X坐标
     * @param {number} y Y坐标
     * @param {Object} element 元素对象
     * @returns {boolean} 是否在元素内
     */
    isPointInElement(x, y, element) {
        switch (element.type) {
            case 'text':
                this.ctx.font = `${element.fontSize}px ${element.fontFamily}`;
                const width = this.ctx.measureText(element.content).width;
                return x >= element.x && 
                       x <= element.x + width && 
                       y >= element.y - element.fontSize && 
                       y <= element.y;
                       
            case 'image':
                return x >= element.x && 
                       x <= element.x + element.width && 
                       y >= element.y && 
                       y <= element.y + element.height;
        }
        return false;
    }
    
    /**
     * 获取设计数据
     * @returns {Object} 设计数据
     */
    getDesignData() {
        return {
            elements: this.elements.map(el => {
                const elementCopy = { ...el };
                
                // 移除图像对象,只保留URL
                if (elementCopy.type === 'image' && elementCopy.image) {
                    elementCopy.src = elementCopy.src;
                    delete elementCopy.image;
                }
                
                return elementCopy;
            }),
            canvasWidth: this.canvas.width,
            canvasHeight: this.canvas.height,
            productId: this.config.productId
        };
    }
}

2. WordPress短代码集成

<?php
// 在class-product-configurator.php中添加短代码方法

/**
 * 注册产品配置器短代码
 */
public function register_shortcode() {
    add_shortcode('cultural_configurator', [$this, 'render_configurator']);
}

/**
 * 渲染产品配置器
 * @param array $atts 短代码属性
 * @return string HTML内容
 */
public function render_configurator($atts) {
    $atts = shortcode_atts([
        'product_id' => 0,
        'width' => '800',
        'height' => '600'
    ], $atts);
    
    if (!$atts['product_id']) {
        return '<p>请指定产品ID</p>';
    }
    
    // 加载产品数据
    $this->product_id = intval($atts['product_id']);
    $this->load_product_data();
    
    if (!$this->product_data) {

return '<p>产品不存在</p>';

}

// 获取可定制区域
$customizable_areas = $this->get_customizable_areas();

// 生成唯一ID
$editor_id = 'cc-editor-' . uniqid();

// 输出HTML结构
ob_start();
?>
<div class="cultural-creator-container">
    <div class="cc-editor-wrapper">
        <div id="<?php echo esc_attr($editor_id); ?>" class="cc-visual-editor"></div>
        
        <div class="cc-toolbar">
            <div class="cc-tool-group">
                <h4>添加元素</h4>
                <button class="cc-btn cc-add-text" data-type="text">
                    <span class="dashicons dashicons-text"></span> 添加文字
                </button>
                <button class="cc-btn cc-add-image" data-type="image">
                    <span class="dashicons dashicons-format-image"></span> 添加图片
                </button>
                <button class="cc-btn cc-add-shape" data-type="shape">
                    <span class="dashicons dashicons-shapes"></span> 添加图形
                </button>
            </div>
            
            <div class="cc-tool-group cc-properties-panel" style="display:none;">
                <h4>属性设置</h4>
                <div class="cc-properties-content"></div>
            </div>
            
            <div class="cc-tool-group">
                <h4>操作</h4>
                <button class="cc-btn cc-save-design">
                    <span class="dashicons dashicons-saved"></span> 保存设计
                </button>
                <button class="cc-btn cc-reset-design">
                    <span class="dashicons dashicons-update"></span> 重置
                </button>
                <button class="cc-btn cc-preview-3d">
                    <span class="dashicons dashicons-visibility"></span> 3D预览
                </button>
            </div>
        </div>
    </div>
    
    <div class="cc-sidebar">
        <div class="cc-price-summary">
            <h3>价格明细</h3>
            <div class="cc-price-breakdown">
                <div class="cc-price-item">
                    <span>基础价格</span>
                    <span class="cc-price-amount">¥<?php echo number_format($this->product_data->base_price, 2); ?></span>
                </div>
                <div class="cc-price-item cc-customization-cost">
                    <span>定制费用</span>
                    <span class="cc-price-amount">¥0.00</span>
                </div>
                <div class="cc-price-total">
                    <span>总计</span>
                    <span class="cc-total-amount">¥<?php echo number_format($this->product_data->base_price, 2); ?></span>
                </div>
            </div>
        </div>
        
        <div class="cc-design-options">
            <h3>设计选项</h3>
            <div class="cc-option-group">
                <label>选择区域:</label>
                <select class="cc-area-selector">
                    <?php foreach ($customizable_areas as $area_key => $area): ?>
                    <option value="<?php echo esc_attr($area_key); ?>">
                        <?php echo esc_html($area['name']); ?>
                    </option>
                    <?php endforeach; ?>
                </select>
            </div>
            
            <div class="cc-option-group">
                <label>上传图片:</label>
                <input type="file" class="cc-image-upload" accept="image/*" style="display:none;">
                <button class="cc-btn cc-upload-btn">选择图片</button>
                <div class="cc-upload-preview"></div>
            </div>
            
            <div class="cc-text-options" style="display:none;">
                <h4>文字设置</h4>
                <input type="text" class="cc-text-input" placeholder="输入文字内容">
                <select class="cc-font-selector">
                    <option value="Arial">Arial</option>
                    <option value="SimSun">宋体</option>
                    <option value="Microsoft YaHei">微软雅黑</option>
                    <option value="KaiTi">楷体</option>
                </select>
                <input type="color" class="cc-text-color" value="#000000">
                <input type="range" class="cc-font-size" min="12" max="72" value="24">
            </div>
        </div>
    </div>
</div>

<script type="text/javascript">
jQuery(document).ready(function($) {
    // 初始化可视化编辑器
    const editorConfig = {
        containerId: '<?php echo esc_js($editor_id); ?>',
        productId: <?php echo intval($atts['product_id']); ?>,
        width: <?php echo intval($atts['width']); ?>,
        height: <?php echo intval($atts['height']); ?>,
        customizableAreas: <?php echo wp_json_encode($customizable_areas); ?>
    };
    
    window.ccEditor = new CulturalCreatorVisualEditor(editorConfig);
    
    // 绑定工具栏事件
    $('.cc-add-text').on('click', function() {
        const area = $('.cc-area-selector').val();
        const textId = ccEditor.addTextElement({
            content: '双击编辑文字',
            area: area,
            x: 100,
            y: 100
        });
        
        // 显示文字设置面板
        $('.cc-text-options').show();
        $('.cc-properties-panel').show();
        $('.cc-properties-content').html(`
            <div class="cc-property-item">
                <label>文字内容:</label>
                <input type="text" class="cc-edit-text" value="双击编辑文字">
            </div>
            <div class="cc-property-item">
                <label>字体大小:</label>
                <input type="range" class="cc-edit-fontsize" min="12" max="72" value="24">
            </div>
            <div class="cc-property-item">
                <label>字体颜色:</label>
                <input type="color" class="cc-edit-color" value="#000000">
            </div>
        `);
    });
    
    // 保存设计
    $('.cc-save-design').on('click', function() {
        const designData = ccEditor.getDesignData();
        
        $.ajax({
            url: '<?php echo admin_url('admin-ajax.php'); ?>',
            type: 'POST',
            data: {
                action: 'cc_save_design',
                nonce: '<?php echo wp_create_nonce('cc_save_design_nonce'); ?>',
                design_data: designData
            },
            success: function(response) {
                if (response.success) {
                    alert('设计保存成功!');
                    // 更新价格
                    $('.cc-customization-cost .cc-price-amount').text('¥' + response.data.customization_cost);
                    $('.cc-total-amount').text('¥' + response.data.total_price);
                } else {
                    alert('保存失败:' + response.data);
                }
            }
        });
    });
});
</script>
<?php

return ob_get_clean();

}


## AJAX处理与数据保存

### 1. AJAX处理器类

<?php
// includes/class-ajax-handler.php

class CulturalCreator_AjaxHandler {


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

/**
 * 初始化AJAX钩子
 */
private function init_hooks() {
    // 保存设计
    add_action('wp_ajax_cc_save_design', [$this, 'save_design']);
    add_action('wp_ajax_nopriv_cc_save_design', [$this, 'save_design']);
    
    // 加载设计
    add_action('wp_ajax_cc_load_design', [$this, 'load_design']);
    add_action('wp_ajax_nopriv_cc_load_design', [$this, 'load_design']);
    
    // 上传图片
    add_action('wp_ajax_cc_upload_image', [$this, 'upload_image']);
    add_action('wp_ajax_nopriv_cc_upload_image', [$this, 'upload_image']);
    
    // 获取产品数据
    add_action('wp_ajax_cc_get_product', [$this, 'get_product_data']);
    add_action('wp_ajax_nopriv_cc_get_product', [$this, 'get_product_data']);
}

/**
 * 保存用户设计
 */
public function save_design() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'cc_save_design_nonce')) {
        wp_die('安全验证失败');
    }
    
    $design_data = json_decode(stripslashes($_POST['design_data']), true);
    
    if (!$design_data || !isset($design_data['productId'])) {
        wp_send_json_error('无效的设计数据');
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'cc_user_designs';
    
    // 获取用户ID或会话ID
    $user_id = is_user_logged_in() ? get_current_user_id() : null;
    $session_id = isset($_COOKIE['cc_session']) ? $_COOKIE['cc_session'] : $this->generate_session_id();
    
    // 计算价格
    $configurator = new CulturalCreator_ProductConfigurator($design_data['productId']);
    $customization_cost = $configurator->calculate_price($design_data['elements']);
    $base_price = floatval($configurator->product_data->base_price);
    $total_price = $base_price + $customization_cost;
    
    // 生成预览图
    $preview_image = $this->generate_preview_image($design_data);
    
    // 保存到数据库
    $result = $wpdb->insert(
        $table_name,
        [
            'user_id' => $user_id,
            'session_id' => $session_id,
            'product_id' => $design_data['productId'],
            'design_data' => json_encode($design_data, JSON_UNESCAPED_UNICODE),
            'preview_image' => $preview_image,
            'total_price' => $total_price,
            'status' => 'draft'
        ],
        ['%d', '%s', '%d', '%s', '%s', '%f', '%s']
    );
    
    if ($result) {
        // 设置会话cookie
        if (!isset($_COOKIE['cc_session'])) {
            setcookie('cc_session', $session_id, time() + 30 * DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
        }
        
        wp_send_json_success([
            'design_id' => $wpdb->insert_id,
            'customization_cost' => number_format($customization_cost, 2),
            'total_price' => number_format($total_price, 2),
            'preview_url' => $preview_image
        ]);
    } else {
        wp_send_json_error('保存失败');
    }
}

/**
 * 生成预览图片
 * @param array $design_data 设计数据
 * @return string 图片URL
 */
private function generate_preview_image($design_data) {
    // 这里简化处理,实际应该使用GD库或ImageMagick生成图片
    $upload_dir = wp_upload_dir();
    $filename = 'cc-preview-' . uniqid() . '.png';
    $filepath = $upload_dir['path'] . '/' . $filename;
    $fileurl = $upload_dir['url'] . '/' . $filename;
    
    // 在实际应用中,这里应该使用canvas生成图片
    // 为了简化,我们创建一个占位图片
    $image = imagecreatetruecolor(400, 300);
    $bg_color = imagecolorallocate($image, 240, 240, 240);
    $text_color = imagecolorallocate($image, 100, 100, 100);
    
    imagefill($image, 0, 0, $bg_color);
    imagestring($image, 5, 150, 140, '设计预览', $text_color);
    
    imagepng($image, $filepath);
    imagedestroy($image);
    
    return $fileurl;
}

/**
 * 生成会话ID
 * @return string 会话ID
 */
private function generate_session_id() {
    return md5(uniqid() . $_SERVER['REMOTE_ADDR'] . time());
}

/**
 * 上传图片
 */
public function upload_image() {
    if (!wp_verify_nonce($_POST['nonce'], 'cc_upload_image_nonce')) {
        wp_die('安全验证失败');
    }
    
    if (!function_exists('wp_handle_upload')) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
    }
    
    $uploadedfile = $_FILES['image'];
    $upload_overrides = ['test_form' => false];
    
    $movefile = wp_handle_upload($uploadedfile, $upload_overrides);
    
    if ($movefile && !isset($movefile['error'])) {
        // 创建WordPress附件
        $attachment = [
            'post_mime_type' => $movefile['type'],
            'post_title' => preg_replace('/.[^.]+$/', '', basename($movefile['file'])),
            'post_content' => '',
            'post_status' => 'inherit'
        ];
        
        $attach_id = wp_insert_attachment($attachment, $movefile['file']);
        
        // 生成缩略图
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        $attach_data = wp_generate_attachment_metadata($attach_id, $movefile['file']);
        wp_update_attachment_metadata($attach_id, $attach_data);
        
        wp_send_json_success([
            'url' => $movefile['url'],
            'id' => $attach_id
        ]);
    } else {
        wp_send_json_error($movefile['error']);
    }
}

}


## 管理后台与产品管理

### 1. 管理界面

<?php
// 在插件主文件中添加管理菜单

add_action('admin_menu', 'cultural_creator_admin_menu');

function cultural_creator_admin_menu() {

add_menu_page(
    '文创产品定制器',
    '文创定制',
    'manage_options',
    'cultural-creator',
    'cultural_creator_admin_page',
    'dashicons-art',
    30
);

add_submenu_page(
    'cultural-creator',
    '产品管理',
    '产品管理',
    'manage_options',
    'cultural-creator-products',
    'cultural_creator_products_page'
);

add_submenu_page(
    'cultural-creator',
    '设计管理',
    '设计管理',
    'manage_options',
    'cultural-creator-designs',
    'cultural_creator_designs_page'
);

add_submenu_page(
    'cultural-creator',
    '设置',
    '设置',
    'manage_options',
    'cultural-creator-settings',
    'cultural_creator_settings_page'
);

}

function cultural_creator_admin_page() {

?>
<div class="wrap">
    <h1>文创产品定制器</h1>
    <div class="cc-admin-dashboard">
        <div class="cc-stats-container">
            <div class="cc-stat-card">
                <h3>总产品数</h3>
                <p class="cc-stat-number"><?php echo cultural_creator_get_product_count(); ?></p>
            </div>
            <div class="cc-stat-card">
                <h3>总设计数</h3>
                <p class="cc-stat-number"><?php echo cultural_creator_get_design_count(); ?></p>
            </div>
            <div class="cc-stat-card">
                <h3>今日设计</h3>
                <p class="cc-stat-number"><?php echo cultural_creator_get_today_designs(); ?></p>
            </div>
        </div>
        
        <div class="cc-quick-actions">
            <h2>快速操作</h2>
            <a href="<?php echo admin_url('admin.php?page=cultural-creator-products&action=add'); ?>" 
               class="button button-primary">
               添加新产品
            </a>
            <a href="<?php echo admin_url('admin.php?page=cultural-creator-designs'); ?>" 
               class="button">
               查看所有设计
            </a>
        </div>
    </div>
</div>
<?php

}

function cultural_creator_products_page() {

$action = isset($_GET['action']) ? $_GET['action'] : 'list';

switch ($action) {
    case 'add':
    case 'edit':
        include CC_PLUGIN_DIR . 'templates/admin-product-edit.php';
        break;
    case 'list':
    default:
        include CC_PLUGIN_DIR . 'templates/admin-product-list.php';
        break;
}

}


## 样式优化与响应式设计

/ assets/css/frontend.css /

.cultural-creator-container {

display: flex;
flex-wrap: wrap;
gap: 20px;
max-width: 1200px;
margin: 0 auto;
padding: 20px;

}

.cc-editor-wrapper {

flex: 1;
min-width: 300px;

}

.cc-visual-editor {

border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);

}

.cc-toolbar {

background: #f5f5f5;
padding: 15px;
border-radius: 8px;
margin-top: 15px;

}

.cc-tool-group {

margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #ddd;

}

.cc-tool-group:last-child {

border-bottom: none;
margin
本文来自网络投稿,不代表本站点的立场,转载请注明出处:https://www.gongxiangcang.com/6646.html

溯源库®作者

漳州柔性供应链服务有限公司 小批量订单定制化服务商( 投稿邮箱:vip@jiaochengku.com)
上一篇
下一篇

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@suyuanku.com

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部