文章目录[隐藏]
WordPress小批量定制插件与PLM系统对接的实战教程
引言:为什么需要WordPress与PLM系统对接?
在产品制造和研发领域,产品生命周期管理(PLM)系统是核心的数据管理平台,而WordPress作为全球最流行的内容管理系统,在企业官网和产品展示中广泛应用。将两者对接可以实现产品数据的自动同步、实时更新和高效展示,特别适合中小型企业的小批量定制需求。
本教程将详细讲解如何开发一个WordPress插件,实现与PLM系统的数据对接,支持小批量定制产品的展示和管理。
环境准备与基础配置
1.1 开发环境要求
- WordPress 5.0+
- PHP 7.2+
- 支持cURL扩展
- PLM系统API访问权限
1.2 创建插件基础结构
在WordPress的wp-content/plugins/目录下创建新插件文件夹plm-integration,并创建主文件:
<?php
/**
* Plugin Name: PLM系统集成插件
* Plugin URI: https://yourwebsite.com/
* Description: 实现WordPress与PLM系统对接,支持小批量定制产品展示
* Version: 1.0.0
* Author: 你的名字
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('PLM_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('PLM_PLUGIN_URL', plugin_dir_url(__FILE__));
define('PLM_API_VERSION', 'v1.0');
// 初始化插件
require_once PLM_PLUGIN_PATH . 'includes/class-plm-core.php';
function run_plm_integration() {
$plugin = new PLM_Core();
$plugin->run();
}
run_plm_integration();
PLM API接口封装类
2.1 创建API客户端类
<?php
/**
* PLM API客户端封装
*/
class PLM_API_Client {
private $api_base_url;
private $api_key;
private $timeout = 30;
/**
* 构造函数
* @param string $base_url PLM系统API基础地址
* @param string $api_key API认证密钥
*/
public function __construct($base_url, $api_key) {
$this->api_base_url = rtrim($base_url, '/');
$this->api_key = $api_key;
}
/**
* 获取产品列表
* @param int $page 页码
* @param int $per_page 每页数量
* @param array $filters 筛选条件
* @return array 产品数据
*/
public function get_products($page = 1, $per_page = 20, $filters = []) {
$endpoint = '/api/products';
$params = [
'page' => $page,
'per_page' => $per_page,
'customizable' => true, // 只获取可定制产品
];
// 合并筛选条件
if (!empty($filters)) {
$params = array_merge($params, $filters);
}
return $this->make_request('GET', $endpoint, $params);
}
/**
* 获取单个产品详情
* @param string $product_id 产品ID
* @return array 产品详情
*/
public function get_product_detail($product_id) {
$endpoint = '/api/products/' . urlencode($product_id);
return $this->make_request('GET', $endpoint);
}
/**
* 获取产品定制选项
* @param string $product_id 产品ID
* @return array 定制选项
*/
public function get_customization_options($product_id) {
$endpoint = '/api/products/' . urlencode($product_id) . '/custom-options';
return $this->make_request('GET', $endpoint);
}
/**
* 提交定制订单
* @param array $order_data 订单数据
* @return array 提交结果
*/
public function submit_custom_order($order_data) {
$endpoint = '/api/orders/custom';
return $this->make_request('POST', $endpoint, $order_data);
}
/**
* 执行API请求
* @param string $method 请求方法
* @param string $endpoint API端点
* @param array $data 请求数据
* @return array 响应数据
*/
private function make_request($method, $endpoint, $data = []) {
$url = $this->api_base_url . $endpoint;
// 设置请求头
$headers = [
'Authorization' => 'Bearer ' . $this->api_key,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
];
// 准备请求参数
$args = [
'method' => $method,
'headers' => $headers,
'timeout' => $this->timeout,
'sslverify' => false, // 根据实际情况调整
];
// 根据请求方法添加数据
if ($method === 'GET' && !empty($data)) {
$url = add_query_arg($data, $url);
} elseif (in_array($method, ['POST', 'PUT', 'PATCH'])) {
$args['body'] = json_encode($data);
}
// 发送请求
$response = wp_remote_request($url, $args);
// 处理响应
if (is_wp_error($response)) {
return [
'success' => false,
'error' => $response->get_error_message()
];
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
return [
'success' => true,
'data' => $data,
'status' => wp_remote_retrieve_response_code($response)
];
}
}
WordPress插件核心类
3.1 主核心类实现
<?php
/**
* PLM集成插件核心类
*/
class PLM_Core {
private $api_client;
private $admin_page;
/**
* 初始化插件
*/
public function __construct() {
// 加载依赖
$this->load_dependencies();
// 初始化API客户端
$api_url = get_option('plm_api_url', '');
$api_key = get_option('plm_api_key', '');
if (!empty($api_url) && !empty($api_key)) {
$this->api_client = new PLM_API_Client($api_url, $api_key);
}
}
/**
* 加载依赖文件
*/
private function load_dependencies() {
// 加载API客户端
require_once PLM_PLUGIN_PATH . 'includes/class-plm-api-client.php';
// 加载管理界面
require_once PLM_PLUGIN_PATH . 'admin/class-plm-admin.php';
// 加载前端展示
require_once PLM_PLUGIN_PATH . 'public/class-plm-public.php';
// 加载短代码
require_once PLM_PLUGIN_PATH . 'includes/class-plm-shortcodes.php';
}
/**
* 运行插件
*/
public function run() {
// 注册激活/停用钩子
register_activation_hook(__FILE__, [$this, 'activate']);
register_deactivation_hook(__FILE__, [$this, 'deactivate']);
// 初始化管理界面
if (is_admin()) {
$this->admin_page = new PLM_Admin($this->api_client);
$this->admin_page->init();
}
// 初始化前端功能
$public = new PLM_Public($this->api_client);
$public->init();
// 初始化短代码
$shortcodes = new PLM_Shortcodes($this->api_client);
$shortcodes->init();
// 注册自定义文章类型
add_action('init', [$this, 'register_custom_post_types']);
}
/**
* 注册自定义文章类型
*/
public function register_custom_post_types() {
// 注册产品自定义类型
register_post_type('plm_product',
[
'labels' => [
'name' => 'PLM产品',
'singular_name' => '产品',
'menu_name' => 'PLM产品',
],
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'thumbnail'],
'rewrite' => ['slug' => 'custom-products'],
'show_in_rest' => true,
]
);
}
/**
* 插件激活时执行
*/
public function activate() {
// 创建必要的数据库表
$this->create_database_tables();
// 设置默认选项
add_option('plm_api_url', '');
add_option('plm_api_key', '');
add_option('plm_sync_interval', 'hourly');
add_option('plm_last_sync', '');
// 添加定时任务
if (!wp_next_scheduled('plm_sync_products_event')) {
wp_schedule_event(time(), 'hourly', 'plm_sync_products_event');
}
}
/**
* 创建数据库表
*/
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'plm_product_sync';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
product_id varchar(100) NOT NULL,
plm_id varchar(100) NOT NULL,
last_sync datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
sync_status varchar(20) DEFAULT 'pending',
data_hash varchar(32) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY plm_id (plm_id),
KEY product_id (product_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
/**
* 插件停用时执行
*/
public function deactivate() {
// 清除定时任务
$timestamp = wp_next_scheduled('plm_sync_products_event');
if ($timestamp) {
wp_unschedule_event($timestamp, 'plm_sync_products_event');
}
}
}
产品同步与缓存机制
4.1 数据同步管理器
<?php
/**
* PLM数据同步管理器
*/
class PLM_Sync_Manager {
private $api_client;
private $batch_size = 50; // 小批量同步
public function __construct($api_client) {
$this->api_client = $api_client;
}
/**
* 同步产品数据
* @param bool $force 是否强制同步
* @return array 同步结果
*/
public function sync_products($force = false) {
global $wpdb;
$results = [
'total' => 0,
'created' => 0,
'updated' => 0,
'skipped' => 0,
'errors' => []
];
$page = 1;
$has_more = true;
while ($has_more) {
// 从PLM获取产品数据
$response = $this->api_client->get_products($page, $this->batch_size);
if (!$response['success']) {
$results['errors'][] = '第' . $page . '页同步失败: ' . $response['error'];
break;
}
$products = $response['data']['products'] ?? [];
$total_pages = $response['data']['total_pages'] ?? 1;
// 处理每个产品
foreach ($products as $product) {
$results['total']++;
// 检查是否为可定制产品
if (!$product['customizable'] && !$force) {
$results['skipped']++;
continue;
}
// 同步到WordPress
$sync_result = $this->sync_single_product($product);
if ($sync_result === 'created') {
$results['created']++;
} elseif ($sync_result === 'updated') {
$results['updated']++;
} else {
$results['errors'][] = '产品' . $product['id'] . '同步失败';
}
}
// 检查是否还有更多页面
$has_more = $page < $total_pages;
$page++;
// 小批量处理,避免超时
if ($page % 5 === 0) {
sleep(1); // 短暂暂停
}
}
// 更新最后同步时间
update_option('plm_last_sync', current_time('mysql'));
return $results;
}
/**
* 同步单个产品
* @param array $product_data 产品数据
* @return string 同步结果
*/
private function sync_single_product($product_data) {
global $wpdb;
$plm_id = $product_data['id'];
$data_hash = md5(serialize($product_data));
// 检查是否已存在
$existing = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}plm_product_sync WHERE plm_id = %s",
$plm_id
));
if ($existing && $existing->data_hash === $data_hash && !$force) {
// 数据未变化,跳过
$wpdb->update(
$wpdb->prefix . 'plm_product_sync',
['last_sync' => current_time('mysql')],
['id' => $existing->id]
);
return 'skipped';
}
// 准备文章数据
$post_data = [
'post_title' => $product_data['name'],
'post_content' => $product_data['description'],
'post_status' => 'publish',
'post_type' => 'plm_product',
'meta_input' => [
'plm_id' => $plm_id,
'product_code' => $product_data['code'],
'base_price' => $product_data['price'],
'min_order_quantity' => $product_data['min_qty'],
'lead_time' => $product_data['lead_time'],
'customization_options' => json_encode($product_data['options'] ?? []),
]
];
// 插入或更新文章
if ($existing) {
$post_data['ID'] = $existing->product_id;
$post_id = wp_update_post($post_data);
$action = 'updated';
} else {
$post_id = wp_insert_post($post_data);
$action = 'created';
}
if (is_wp_error($post_id)) {
return false;
}
// 更新同步记录
$sync_data = [
'product_id' => $post_id,
'plm_id' => $plm_id,
'last_sync' => current_time('mysql'),
'sync_status' => 'success',
'data_hash' => $data_hash
];
if ($existing) {
$wpdb->update(
$wpdb->prefix . 'plm_product_sync',
$sync_data,
['id' => $existing->id]
);
} else {
$wpdb->insert(
$wpdb->prefix . 'plm_product_sync',
$sync_data
);
}
return $action;
}
}
前端定制展示与交互
5.1 产品定制短代码
<?php
/**
* 产品定制短代码类
*/
class PLM_Shortcodes {
private $api_client;
public function __construct($api_client) {
$this->api_client = $api_client;
}
public function init() {
// 注册短代码
add_shortcode('plm_custom_product', [$this, 'render_custom_product']);
add_shortcode('plm_product_list', [$this, 'render_product_list']);
// 注册AJAX处理
add_action('wp_ajax_plm_get_custom_options', [$this, 'ajax_get_custom_options']);
add_action('wp_ajax_nopriv_plm_get_custom_options', [$this, 'ajax_get_custom_options']);
add_action('wp_ajax_plm_submit_custom_order', [$this, 'ajax_submit_custom_order']);
add_action('wp_ajax_nopriv_plm_submit_custom_order', [$this, 'ajax_submit_custom_order']);
}
/**
* 渲染产品定制界面
* @param array $atts 短代码属性
* @return string HTML内容
*/
public function render_custom_product($atts) {
$atts = shortcode_atts([
'id' => '', // PLM产品ID或WordPress文章ID
'show_price' => 'yes',
'show_options' => 'yes',
], $atts);
// 获取产品数据
$product = $this->get_product_data($atts['id']);
if (!$product) {
return '<div class="plm-error">产品不存在或无法加载</div>';
}
ob_start();
?>
<div class="plm-custom-product" data-product-id="<?php echo esc_attr($product['plm_id']); ?>">
<div class="plm-product-header">
<h2><?php echo esc_html($product['name']); ?></h2>
<?php if ($atts['show_price'] === 'yes'): ?>
<div class="plm-price">
基础价格: <span class="price-amount">¥<?php echo number_format($product['price'], 2); ?></span>
</div>
<?php endif; ?>
</div>
<div class="plm-product-details">
<div class="plm-description">
<?php echo wp_kses_post($product['description']); ?>
</div>
<?php if ($atts['show_options'] === 'yes' && !empty($product['options'])): ?>
<div class="plm-customization-section">
<h3>定制选项</h3>
<form id="plm-custom-form-<?php echo esc_attr($product['plm_id']); ?>" class="plm-custom-form">
<input type="hidden" name="product_id" value="<?php echo esc_attr($product['plm_id']); ?>">
<?php foreach ($product['options'] as $option): ?>
<div class="plm-option-group">
<label for="option-<?php echo esc_attr($option['id']); ?>">
<?php echo esc_html($option['name']); ?>
<?php if ($option['required']): ?>
<span class="required">*</span>
<?php endif; ?>
</label>
<?php echo $this->render_option_field($option); ?>
<?php if (!empty($option['description'])): ?>
<p class="option-description"><?php echo esc_html($option['description']); ?></p>
<?php endif; ?>
</div>
<?php endforeach; ?>
<div class="plm-quantity-group">
<label for="quantity">订购数量</label>
<input type="number"
id="quantity"
name="quantity"
min="<?php echo esc_attr($product['min_qty']); ?>"
value="<?php echo esc_attr($product['min_qty']); ?>"
class="plm-quantity-input">
<span class="min-qty">(最小起订量: <?php echo esc_html($product['min_qty']); ?>)</span>
</div>
<div class="plm-calculator">
<h4>价格计算</h4>
<div class="price-breakdown">
<div class="price-row">
<span>基础价格:</span>
<span class="base-price">¥<?php echo number_format($product['price'], 2); ?></span>
</div>
<div class="price-row">
<span>定制选项:</span>
<span class="options-price">¥0.00</span>
</div>
<div class="price-row total">
<span>总计:</span>
<span class="total-price">¥<?php echo number_format($product['price'], 2); ?></span>
</div>
</div>
</div>
<div class="plm-form-actions">
<button type="button" class="plm-calculate-btn">计算价格</button>
<button type="submit" class="plm-submit-btn">提交定制需求</button>
</div>
</form>
</div>
<?php endif; ?>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
var productId = '<?php echo esc_js($product['plm_id']); ?>';
var basePrice = <?php echo $product['price']; ?>;
// 价格计算函数
function calculateTotalPrice() {
var optionsPrice = 0;
var quantity = parseInt($('#quantity').val()) || <?php echo $product['min_qty']; ?>;
// 计算选项价格
$('.plm-option-input').each(function() {
var $this = $(this);
var optionPrice = 0;
if ($this.is(':checkbox') || $this.is(':radio')) {
if ($this.is(':checked')) {
optionPrice = parseFloat($this.data('price')) || 0;
}
} else if ($this.is('select')) {
var selectedOption = $this.find('option:selected');
optionPrice = parseFloat(selectedOption.data('price')) || 0;
} else if ($this.is('input[type="number"]')) {
var value = parseFloat($this.val()) || 0;
var unitPrice = parseFloat($this.data('unit-price')) || 0;
optionPrice = value * unitPrice;
}
optionsPrice += optionPrice;
});
// 计算总计
var totalPrice = (basePrice + optionsPrice) * quantity;
// 更新显示
$('.options-price').text('¥' + optionsPrice.toFixed(2));
$('.total-price').text('¥' + totalPrice.toFixed(2));
}
// 绑定事件
$('.plm-option-input').on('change', calculateTotalPrice);
$('#quantity').on('input', calculateTotalPrice);
$('.plm-calculate-btn').on('click', calculateTotalPrice);
// 表单提交
$('#plm-custom-form-' + productId).on('submit', function(e) {
e.preventDefault();
var formData = $(this).serializeArray();
var quantity = $('#quantity').val();
// 验证必填项
var isValid = true;
$('.plm-option-group .required').each(function() {
var optionId = $(this).closest('.plm-option-group').find('.plm-option-input').attr('id');
var $input = $('#' + optionId);
if ($input.is(':checkbox') || $input.is(':radio')) {
var name = $input.attr('name');
if (!$('input[name="' + name + '"]:checked').length) {
isValid = false;
$input.closest('.plm-option-group').addClass('error');
}
} else if (!$input.val().trim()) {
isValid = false;
$input.closest('.plm-option-group').addClass('error');
}
});
if (!isValid) {
alert('请填写所有必填选项');
return;
}
// 验证数量
if (quantity < <?php echo $product['min_qty']; ?>) {
alert('订购数量不能小于最小起订量');
return;
}
// 显示加载状态
$('.plm-submit-btn').prop('disabled', true).text('提交中...');
// 发送AJAX请求
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'plm_submit_custom_order',
nonce: '<?php echo wp_create_nonce('plm_custom_order'); ?>',
form_data: formData,
quantity: quantity,
product_id: productId
},
success: function(response) {
if (response.success) {
alert('定制需求提交成功!我们的客服将尽快与您联系。');
$('#plm-custom-form-' + productId)[0].reset();
calculateTotalPrice();
} else {
alert('提交失败: ' + response.data.message);
}
},
error: function() {
alert('网络错误,请稍后重试');
},
complete: function() {
$('.plm-submit-btn').prop('disabled', false).text('提交定制需求');
}
});
});
});
</script>
<?php
return ob_get_clean();
}
/**
* 渲染选项字段
* @param array $option 选项数据
* @return string HTML字段
*/
private function render_option_field($option) {
$field_id = 'option-' . $option['id'];
$field_name = 'option[' . $option['id'] . ']';
switch ($option['type']) {
case 'select':
$html = '<select id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '" class="plm-option-input">';
$html .= '<option value="">请选择</option>';
foreach ($option['choices'] as $choice) {
$price_attr = isset($choice['price']) ? ' data-price="' . esc_attr($choice['price']) . '"' : '';
$html .= '<option value="' . esc_attr($choice['value']) . '"' . $price_attr . '>';
$html .= esc_html($choice['label']);
if (isset($choice['price']) && $choice['price'] > 0) {
$html .= ' (+¥' . number_format($choice['price'], 2) . ')';
}
$html .= '</option>';
}
$html .= '</select>';
break;
case 'radio':
$html = '';
foreach ($option['choices'] as $choice) {
$price_attr = isset($choice['price']) ? ' data-price="' . esc_attr($choice['price']) . '"' : '';
$html .= '<label class="plm-radio-label">';
$html .= '<input type="radio" name="' . esc_attr($field_name) . '" value="' . esc_attr($choice['value']) . '"';
$html .= ' class="plm-option-input"' . $price_attr . '>';
$html .= esc_html($choice['label']);
if (isset($choice['price']) && $choice['price'] > 0) {
$html .= ' (+¥' . number_format($choice['price'], 2) . ')';
}
$html .= '</label><br>';
}
break;
case 'checkbox':
$html = '';
foreach ($option['choices'] as $choice) {
$price_attr = isset($choice['price']) ? ' data-price="' . esc_attr($choice['price']) . '"' : '';
$html .= '<label class="plm-checkbox-label">';
$html .= '<input type="checkbox" name="' . esc_attr($field_name) . '[]" value="' . esc_attr($choice['value']) . '"';
$html .= ' class="plm-option-input"' . $price_attr . '>';
$html .= esc_html($choice['label']);
if (isset($choice['price']) && $choice['price'] > 0) {
$html .= ' (+¥' . number_format($choice['price'], 2) . ')';
}
$html .= '</label><br>';
}
break;
case 'number':
$min = isset($option['min']) ? $option['min'] : 0;
$max = isset($option['max']) ? $option['max'] : '';
$step = isset($option['step']) ? $option['step'] : 1;
$unit_price = isset($option['unit_price']) ? $option['unit_price'] : 0;
$html = '<input type="number" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '"';
$html .= ' min="' . esc_attr($min) . '"';
if ($max) $html .= ' max="' . esc_attr($max) . '"';
$html .= ' step="' . esc_attr($step) . '"';
$html .= ' data-unit-price="' . esc_attr($unit_price) . '"';
$html .= ' class="plm-option-input" value="' . esc_attr($min) . '">';
break;
case 'text':
default:
$html = '<input type="text" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '" class="plm-option-input">';
break;
}
return $html;
}
/**
* 获取产品数据
* @param string $id 产品标识
* @return array|false 产品数据
*/
private function get_product_data($id) {
// 先从缓存中获取
$cache_key = 'plm_product_' . md5($id);
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
// 如果是数字,假设是WordPress文章ID
if (is_numeric($id)) {
$post = get_post($id);
if ($post && $post->post_type === 'plm_product') {
$product = [
'plm_id' => get_post_meta($id, 'plm_id', true),
'name' => $post->post_title,
'description' => $post->post_content,
'price' => get_post_meta($id, 'base_price', true),
'min_qty' => get_post_meta($id, 'min_order_quantity', true),
'options' => json_decode(get_post_meta($id, 'customization_options', true), true)
];
// 缓存1小时
set_transient($cache_key, $product, HOUR_IN_SECONDS);
return $product;
}
}
// 否则尝试从PLM API获取
if ($this->api_client) {
$response = $this->api_client->get_product_detail($id);
if ($response['success']) {
$product = $response['data'];
set_transient($cache_key, $product, HOUR_IN_SECONDS);
return $product;
}
}
return false;
}
/**
* AJAX获取定制选项
*/
public function ajax_get_custom_options() {
check_ajax_referer('plm_custom_options', 'nonce');
$product_id = sanitize_text_field($_POST['product_id']);
if (!$this->api_client) {
wp_send_json_error(['message' => 'API客户端未初始化']);
}
$response = $this->api_client->get_customization_options($product_id);
if ($response['success']) {
wp_send_json_success($response['data']);
} else {
wp_send_json_error(['message' => $response['error']]);
}
}
/**
* AJAX提交定制订单
*/
public function ajax_submit_custom_order() {
check_ajax_referer('plm_custom_order', 'nonce');
// 验证用户
$user_id = get_current_user_id();
if (!$user_id) {
// 如果是未登录用户,可以创建临时用户或要求登录
wp_send_json_error(['message' => '请先登录']);
}
// 收集表单数据
$order_data = [
'product_id' => sanitize_text_field($_POST['product_id']),
'quantity' => intval($_POST['quantity']),
'user_id' => $user_id,
'user_email' => wp_get_current_user()->user_email,
'options' => [],
'submitted_at' => current_time('mysql')
];
// 解析选项数据
if (!empty($_POST['form_data'])) {
parse_str(http_build_query($_POST['form_data']), $form_data);
if (isset($form_data['option'])) {
$order_data['options'] = $form_data['option'];
}
}
// 验证数据
if (empty($order_data['product_id']) || $order_data['quantity'] <= 0) {
wp_send_json_error(['message' => '无效的订单数据']);
}
// 保存到数据库
global $wpdb;
$table_name = $wpdb->prefix . 'plm_custom_orders';
$result = $wpdb->insert(
$table_name,
[
'order_number' => 'CUST-' . date('Ymd') . '-' . wp_generate_password(6, false),
'product_id' => $order_data['product_id'],
'user_id' => $order_data['user_id'],
'quantity' => $order_data['quantity'],
'options' => json_encode($order_data['options']),
'status' => 'pending',
'submitted_at' => $order_data['submitted_at']
],
['%s', '%s', '%d', '%d', '%s', '%s', '%s']
);
if ($result) {
$order_id = $wpdb->insert_id;
// 发送通知邮件
$this->send_order_notification($order_id, $order_data);
// 可选:同步到PLM系统
if ($this->api_client) {
$plm_response = $this->api_client->submit_custom_order($order_data);
if ($plm_response['success']) {
$wpdb->update(
$table_name,
['plm_order_id' => $plm_response['data']['order_id']],
['id' => $order_id]
);
}
}
wp_send_json_success([
'message' => '订单提交成功',
'order_number' => $wpdb->get_var("SELECT order_number FROM $table_name WHERE id = $order_id")
]);
} else {
wp_send_json_error(['message' => '订单保存失败']);
}
}
/**
* 发送订单通知
*/
private function send_order_notification($order_id, $order_data) {
$to = get_option('admin_email');
$subject = '新的产品定制订单 #' . $order_id;
$message = "收到新的产品定制订单:nn";
$message .= "订单ID: " . $order_id . "n";
$message .= "产品ID: " . $order_data['product_id'] . "n";
$message .= "数量: " . $order_data['quantity'] . "n";
$message .= "用户: " . $order_data['user_email'] . "


