文章目录[隐藏]
WordPress柔性供应链软件实现多渠道库存同步的技术详解
引言:现代电商库存管理的挑战
在当今多平台销售的时代,企业往往同时在亚马逊、淘宝、自建网站等多个渠道销售商品。库存同步成为电商运营的核心挑战之一——某个渠道售出一件商品,其他渠道的库存需要实时更新,否则会导致超卖或缺货。WordPress作为全球最流行的内容管理系统,结合柔性供应链软件,能够有效解决这一难题。
本文将深入探讨如何在WordPress环境中实现多渠道库存同步,涵盖技术架构、核心代码实现和最佳实践。
系统架构设计
整体架构概览
一个典型的WordPress多渠道库存同步系统包含以下核心组件:
- 中央库存数据库 - 作为单一事实来源
- 渠道适配器层 - 连接各个销售渠道API
- 同步引擎 - 处理库存变更和冲突解决
- 监控与报警系统 - 确保系统可靠性
/**
* WordPress多渠道库存同步系统主类
* 负责协调各个组件的工作
*/
class MultiChannelInventorySync {
private $central_inventory_db;
private $channel_adapters = [];
private $sync_engine;
private $logger;
public function __construct() {
$this->central_inventory_db = new CentralInventoryDB();
$this->sync_engine = new SyncEngine();
$this->logger = new InventoryLogger();
$this->init_channel_adapters();
}
/**
* 初始化所有渠道适配器
*/
private function init_channel_adapters() {
// 支持的销售渠道
$channels = ['woocommerce', 'amazon', 'shopify', 'ebay'];
foreach ($channels as $channel) {
$adapter_class = ucfirst($channel) . 'Adapter';
if (class_exists($adapter_class)) {
$this->channel_adapters[$channel] = new $adapter_class();
}
}
}
/**
* 主同步方法
*/
public function sync_all_channels() {
$this->logger->log('开始全渠道库存同步');
// 从中央库存库获取当前库存状态
$central_inventory = $this->central_inventory_db->get_all_inventory();
foreach ($this->channel_adapters as $channel => $adapter) {
try {
$this->sync_channel($channel, $adapter, $central_inventory);
} catch (Exception $e) {
$this->logger->log_error("渠道 {$channel} 同步失败: " . $e->getMessage());
}
}
$this->logger->log('全渠道库存同步完成');
}
}
中央库存数据库设计
数据库表结构
中央库存数据库需要存储产品信息、库存数量、渠道映射等关键数据。
/**
* 中央库存数据库操作类
*/
class CentralInventoryDB {
/**
* 创建库存相关数据库表
* 在插件激活时调用
*/
public function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 产品主表
$products_table = $wpdb->prefix . 'flexible_inventory_products';
$products_sql = "CREATE TABLE IF NOT EXISTS $products_table (
product_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
sku VARCHAR(100) NOT NULL UNIQUE,
product_name VARCHAR(255) NOT NULL,
description TEXT,
central_stock INT NOT NULL DEFAULT 0,
reserved_stock INT NOT NULL DEFAULT 0,
available_stock INT GENERATED ALWAYS AS (central_stock - reserved_stock) STORED,
low_stock_threshold INT DEFAULT 10,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (product_id),
INDEX idx_sku (sku),
INDEX idx_available_stock (available_stock)
) $charset_collate;";
// 渠道库存表
$channel_table = $wpdb->prefix . 'flexible_inventory_channels';
$channel_sql = "CREATE TABLE IF NOT EXISTS $channel_table (
channel_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
product_id BIGINT(20) UNSIGNED NOT NULL,
channel_name VARCHAR(50) NOT NULL,
channel_product_id VARCHAR(100),
channel_stock INT NOT NULL DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE,
sync_enabled BOOLEAN DEFAULT TRUE,
last_sync TIMESTAMP NULL,
FOREIGN KEY (product_id) REFERENCES $products_table(product_id) ON DELETE CASCADE,
PRIMARY KEY (channel_id),
UNIQUE KEY unique_channel_product (product_id, channel_name),
INDEX idx_channel_name (channel_name)
) $charset_collate;";
// 库存变更日志表
$log_table = $wpdb->prefix . 'flexible_inventory_logs';
$log_sql = "CREATE TABLE IF NOT EXISTS $log_table (
log_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
product_id BIGINT(20) UNSIGNED NOT NULL,
channel_name VARCHAR(50),
change_type ENUM('sale', 'restock', 'adjustment', 'sync') NOT NULL,
old_stock INT,
new_stock INT,
change_amount INT,
reference_id VARCHAR(100),
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (log_id),
INDEX idx_product_id (product_id),
INDEX idx_created_at (created_at)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($products_sql);
dbDelta($channel_sql);
dbDelta($log_sql);
}
/**
* 更新中央库存
*/
public function update_central_stock($product_id, $new_stock, $change_type = 'adjustment', $channel = null) {
global $wpdb;
$products_table = $wpdb->prefix . 'flexible_inventory_products';
// 获取当前库存
$current_stock = $wpdb->get_var(
$wpdb->prepare("SELECT central_stock FROM $products_table WHERE product_id = %d", $product_id)
);
// 更新库存
$wpdb->update(
$products_table,
['central_stock' => $new_stock],
['product_id' => $product_id],
['%d'],
['%d']
);
// 记录库存变更
$this->log_stock_change(
$product_id,
$channel,
$change_type,
$current_stock,
$new_stock,
$new_stock - $current_stock
);
return true;
}
}
渠道适配器实现
WooCommerce适配器示例
/**
* WooCommerce渠道适配器
* 处理与WooCommerce商店的库存同步
*/
class WoocommerceAdapter {
private $api_endpoint;
private $api_key;
private $api_secret;
public function __construct() {
// 从WordPress设置获取API凭证
$this->api_endpoint = get_option('wc_api_endpoint', site_url('/wp-json/wc/v3/'));
$this->api_key = get_option('wc_api_key');
$this->api_secret = get_option('wc_api_secret');
}
/**
* 从WooCommerce获取当前库存
*/
public function fetch_current_inventory() {
$inventory_data = [];
try {
// 使用WooCommerce REST API获取产品
$response = wp_remote_get(
$this->api_endpoint . 'products?per_page=100',
[
'headers' => [
'Authorization' => 'Basic ' . base64_encode($this->api_key . ':' . $this->api_secret)
],
'timeout' => 30
]
);
if (is_wp_error($response)) {
throw new Exception('WooCommerce API请求失败: ' . $response->get_error_message());
}
$products = json_decode(wp_remote_retrieve_body($response), true);
foreach ($products as $product) {
$inventory_data[] = [
'sku' => $product['sku'],
'stock_quantity' => $product['stock_quantity'],
'manage_stock' => $product['manage_stock'],
'product_id' => $product['id']
];
}
} catch (Exception $e) {
error_log('WooCommerce库存获取失败: ' . $e->getMessage());
return false;
}
return $inventory_data;
}
/**
* 更新WooCommerce中的库存
*/
public function update_inventory($sku, $new_stock) {
try {
// 首先通过SKU查找产品ID
$product_id = $this->get_product_id_by_sku($sku);
if (!$product_id) {
throw new Exception("未找到SKU为 {$sku} 的产品");
}
// 更新库存
$response = wp_remote_post(
$this->api_endpoint . "products/{$product_id}",
[
'headers' => [
'Authorization' => 'Basic ' . base64_encode($this->api_key . ':' . $this->api_secret),
'Content-Type' => 'application/json'
],
'body' => json_encode([
'stock_quantity' => $new_stock,
'manage_stock' => true
]),
'method' => 'PUT',
'timeout' => 15
]
);
if (is_wp_error($response)) {
throw new Exception('库存更新失败: ' . $response->get_error_message());
}
return true;
} catch (Exception $e) {
error_log('WooCommerce库存更新失败: ' . $e->getMessage());
return false;
}
}
}
同步引擎与冲突解决
智能同步算法
/**
* 同步引擎核心类
* 处理库存同步逻辑和冲突解决
*/
class SyncEngine {
/**
* 执行库存同步
* 使用乐观锁机制避免冲突
*/
public function sync_inventory($product_id, $channel_updates) {
global $wpdb;
$products_table = $wpdb->prefix . 'flexible_inventory_products';
$channels_table = $wpdb->prefix . 'flexible_inventory_channels';
// 开始事务
$wpdb->query('START TRANSACTION');
try {
// 使用行级锁锁定产品记录
$product = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM $products_table WHERE product_id = %d FOR UPDATE",
$product_id
),
ARRAY_A
);
if (!$product) {
throw new Exception("产品不存在");
}
$current_central_stock = $product['central_stock'];
$new_central_stock = $current_central_stock;
// 处理每个渠道的更新
foreach ($channel_updates as $channel_name => $channel_data) {
$channel_stock = $channel_data['stock'];
$change_type = $channel_data['change_type'];
// 更新渠道库存记录
$wpdb->update(
$channels_table,
[
'channel_stock' => $channel_stock,
'last_sync' => current_time('mysql')
],
[
'product_id' => $product_id,
'channel_name' => $channel_name
]
);
// 根据渠道变更调整中央库存
if ($change_type === 'sale') {
$new_central_stock -= $channel_data['sold_quantity'];
} elseif ($change_type === 'restock') {
$new_central_stock += $channel_data['restocked_quantity'];
}
}
// 更新中央库存
$wpdb->update(
$products_table,
['central_stock' => $new_central_stock],
['product_id' => $product_id]
);
// 重新计算并同步到所有渠道
$this->redistribute_stock_to_channels($product_id, $new_central_stock);
$wpdb->query('COMMIT');
return true;
} catch (Exception $e) {
$wpdb->query('ROLLBACK');
error_log('库存同步失败: ' . $e->getMessage());
return false;
}
}
/**
* 库存重新分配算法
* 根据渠道权重分配可用库存
*/
private function redistribute_stock_to_channels($product_id, $total_available_stock) {
global $wpdb;
$channels_table = $wpdb->prefix . 'flexible_inventory_channels';
// 获取所有活跃渠道及其权重
$channels = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM $channels_table
WHERE product_id = %d AND is_active = 1 AND sync_enabled = 1
ORDER BY channel_weight DESC",
$product_id
),
ARRAY_A
);
if (empty($channels)) {
return;
}
// 计算总权重
$total_weight = array_sum(array_column($channels, 'channel_weight'));
// 分配库存
foreach ($channels as $channel) {
$allocated_stock = floor(($channel['channel_weight'] / $total_weight) * $total_available_stock);
// 更新渠道适配器
$adapter = $this->get_adapter_for_channel($channel['channel_name']);
if ($adapter) {
$adapter->update_inventory($channel['sku'], $allocated_stock);
}
}
}
}
实时同步与Webhook集成
Webhook处理器
/**
* Webhook处理器
* 接收来自各渠道的实时库存变更通知
*/
class InventoryWebhookHandler {
/**
* 处理WooCommerce库存变更Webhook
*/
public function handle_woocommerce_webhook($request) {
// 验证Webhook签名
if (!$this->verify_webhook_signature($request)) {
return new WP_Error('unauthorized', '无效的Webhook签名', ['status' => 401]);
}
$data = $request->get_json_params();
// 提取关键信息
$sku = $data['sku'];
$new_stock = $data['stock_quantity'];
$order_id = $data['order_id'] ?? null;
// 记录库存变更
$this->process_stock_change($sku, $new_stock, 'woocommerce', $order_id);
// 触发同步到其他渠道
$this->trigger_cross_channel_sync($sku);
return ['success' => true, 'message' => '库存更新已处理'];
}
/**
* 触发跨渠道同步
*/
private function trigger_cross_channel_sync($sku) {
// 获取产品ID
$product_id = $this->get_product_id_by_sku($sku);
if (!$product_id) {
return;
}
// 异步执行同步任务
wp_schedule_single_event(
time() + 5, // 5秒后执行
'flexible_inventory_sync_event',
[$product_id]
);
}
/**
* 异步同步任务
*/
public function async_sync_task($product_id) {
$sync_system = new MultiChannelInventorySync();
$sync_system->sync_product($product_id);
}
}
// 注册Webhook端点
add_action('rest_api_init', function() {
register_rest_route('flexible-inventory/v1', '/webhook/woocommerce', [
'methods' => 'POST',
'callback' => [new InventoryWebhookHandler(), 'handle_woocommerce_webhook'],
'permission_callback' => '__return_true'
]);
});
监控与报警系统
库存健康监控
/**
* 库存监控系统
*/
class InventoryMonitor {
/**
* 检查低库存产品
*/
public function check_low_stock() {
global $wpdb;
$products_table = $wpdb->prefix . 'flexible_inventory_products';
$low_stock_products = $wpdb->get_results(
"SELECT * FROM $products_table
WHERE available_stock <= low_stock_threshold
AND available_stock > 0"
);
if (!empty($low_stock_products)) {
$this->send_low_stock_alert($low_stock_products);
}
// 检查缺货产品
$out_of_stock_products = $wpdb->get_results(
"SELECT * FROM $products_table WHERE available_stock <= 0"
);
if (!empty($out_of_stock_products)) {
$this->send_out_of_stock_alert($out_of_stock_products);
}
}
/**
* 同步状态监控
*/
public function check_sync_health() {
global $wpdb;
$channels_table = $wpdb->prefix . 'flexible_inventory_channels';
// 查找超过1小时未同步的渠道
$stale_channels = $wpdb->get_results(
"SELECT * FROM $channels_table
WHERE last_sync < DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND sync_enabled = 1"
);
if (!empty($stale_channels)) {
$this->send_sync_alert($stale_channels);
}
}
}
性能优化与缓存策略
Redis缓存集成
/**
* 库存缓存管理器
数据库查询压力
*/
class InventoryCacheManager {
private $redis_client;
private $cache_ttl = 300; // 5分钟缓存
public function __construct() {
if (class_exists('Redis')) {
$this->redis_client = new Redis();
$this->connect_redis();
}
}
/**
* 连接Redis服务器
*/
private function connect_redis() {
try {
$this->redis_client->connect(
get_option('redis_host', '127.0.0.1'),
get_option('redis_port', 6379),
2.5 // 超时时间
);
if ($password = get_option('redis_password')) {
$this->redis_client->auth($password);
}
// 选择数据库
$this->redis_client->select(get_option('redis_db', 0));
} catch (Exception $e) {
error_log('Redis连接失败: ' . $e->getMessage());
$this->redis_client = null;
}
}
/**
* 获取缓存库存数据
*/
public function get_cached_inventory($product_id) {
if (!$this->redis_client) {
return false;
}
$cache_key = "inventory:product:{$product_id}";
$cached_data = $this->redis_client->get($cache_key);
if ($cached_data) {
return json_decode($cached_data, true);
}
return false;
}
/**
* 设置库存缓存
*/
public function set_inventory_cache($product_id, $inventory_data) {
if (!$this->redis_client) {
return false;
}
$cache_key = "inventory:product:{$product_id}";
return $this->redis_client->setex(
$cache_key,
$this->cache_ttl,
json_encode($inventory_data)
);
}
/**
* 批量获取库存缓存
*/
public function get_batch_inventory_cache($product_ids) {
if (!$this->redis_client || empty($product_ids)) {
return [];
}
$cache_keys = array_map(function($id) {
return "inventory:product:{$id}";
}, $product_ids);
$cached_items = $this->redis_client->mget($cache_keys);
$result = [];
foreach ($cached_items as $index => $cached_data) {
if ($cached_data) {
$result[$product_ids[$index]] = json_decode($cached_data, true);
}
}
return $result;
}
/**
* 清除库存缓存
*/
public function clear_inventory_cache($product_id = null) {
if (!$this->redis_client) {
return false;
}
if ($product_id) {
// 清除单个产品缓存
$cache_key = "inventory:product:{$product_id}";
$this->redis_client->del($cache_key);
// 清除相关渠道缓存
$pattern = "inventory:channels:{$product_id}:*";
$keys = $this->redis_client->keys($pattern);
if (!empty($keys)) {
$this->redis_client->del($keys);
}
} else {
// 清除所有库存相关缓存
$patterns = ["inventory:product:*", "inventory:channels:*"];
foreach ($patterns as $pattern) {
$keys = $this->redis_client->keys($pattern);
if (!empty($keys)) {
$this->redis_client->del($keys);
}
}
}
return true;
}
}
/**
- 带缓存的库存服务
*/
class CachedInventoryService {
private $db_service;
private $cache_manager;
public function __construct() {
$this->db_service = new CentralInventoryDB();
$this->cache_manager = new InventoryCacheManager();
}
/**
* 获取产品库存(带缓存)
*/
public function get_product_inventory($product_id) {
// 首先尝试从缓存获取
$cached_data = $this->cache_manager->get_cached_inventory($product_id);
if ($cached_data !== false) {
// 检查缓存是否过期(额外验证)
if ($this->validate_cache_freshness($cached_data)) {
return $cached_data;
}
}
// 缓存未命中或已过期,从数据库获取
$inventory_data = $this->db_service->get_product_inventory($product_id);
if ($inventory_data) {
// 添加时间戳并存入缓存
$inventory_data['cached_at'] = time();
$this->cache_manager->set_inventory_cache($product_id, $inventory_data);
}
return $inventory_data;
}
/**
* 验证缓存新鲜度
*/
private function validate_cache_freshness($cached_data) {
if (!isset($cached_data['cached_at'])) {
return false;
}
$cache_age = time() - $cached_data['cached_at'];
$max_cache_age = 300; // 最大缓存年龄5分钟
return $cache_age <= $max_cache_age;
}
/**
* 更新库存并清除缓存
*/
public function update_inventory_with_cache($product_id, $new_stock, $channel = null) {
// 更新数据库
$result = $this->db_service->update_central_stock($product_id, $new_stock, 'adjustment', $channel);
if ($result) {
// 清除相关缓存
$this->cache_manager->clear_inventory_cache($product_id);
// 异步更新缓存
$this->async_refresh_cache($product_id);
}
return $result;
}
/**
* 异步刷新缓存
*/
private function async_refresh_cache($product_id) {
// 使用WordPress的异步任务系统
wp_schedule_single_event(
time() + 2, // 2秒后执行
'refresh_inventory_cache',
[$product_id]
);
}
}
// 注册缓存刷新钩子
add_action('refresh_inventory_cache', function($product_id) {
$service = new CachedInventoryService();
$service->get_product_inventory($product_id); // 这会重新生成缓存
});
// 库存变更时清除缓存
add_action('inventory_updated', function($product_id) {
$cache_manager = new InventoryCacheManager();
$cache_manager->clear_inventory_cache($product_id);
});
批量处理与队列系统
异步任务队列
/**
* 库存同步队列管理器
* 处理大批量库存更新
*/
class InventorySyncQueue {
private $queue_table;
public function __construct() {
global $wpdb;
$this->queue_table = $wpdb->prefix . 'flexible_inventory_queue';
}
/**
* 创建队列表
*/
public function create_queue_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS {$this->queue_table} (
job_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
job_type VARCHAR(50) NOT NULL,
product_id BIGINT(20) UNSIGNED NOT NULL,
channel_name VARCHAR(50),
payload LONGTEXT,
status ENUM('pending', 'processing', 'completed', 'failed') DEFAULT 'pending',
attempts INT DEFAULT 0,
max_attempts INT DEFAULT 3,
last_attempt TIMESTAMP NULL,
scheduled_for TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP NULL,
error_message TEXT,
PRIMARY KEY (job_id),
INDEX idx_status (status),
INDEX idx_scheduled (scheduled_for),
INDEX idx_product_channel (product_id, channel_name)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
/**
* 添加同步任务到队列
*/
public function enqueue_sync_task($product_id, $channel_name = null, $payload = null) {
global $wpdb;
$data = [
'job_type' => 'inventory_sync',
'product_id' => $product_id,
'channel_name' => $channel_name,
'payload' => $payload ? json_encode($payload) : null,
'status' => 'pending'
];
$wpdb->insert($this->queue_table, $data);
return $wpdb->insert_id;
}
/**
* 处理队列中的任务
*/
public function process_queue($limit = 10) {
global $wpdb;
// 获取待处理任务
$jobs = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$this->queue_table}
WHERE status = 'pending'
AND scheduled_for <= NOW()
AND attempts < max_attempts
ORDER BY created_at ASC
LIMIT %d",
$limit
),
ARRAY_A
);
foreach ($jobs as $job) {
$this->process_job($job);
}
return count($jobs);
}
/**
* 处理单个任务
*/
private function process_job($job) {
global $wpdb;
// 标记为处理中
$wpdb->update(
$this->queue_table,
[
'status' => 'processing',
'last_attempt' => current_time('mysql'),
'attempts' => $job['attempts'] + 1
],
['job_id' => $job['job_id']]
);
try {
switch ($job['job_type']) {
case 'inventory_sync':
$this->process_inventory_sync($job);
break;
case 'batch_update':
$this->process_batch_update($job);
break;
case 'channel_sync':
$this->process_channel_sync($job);
break;
}
// 标记为完成
$wpdb->update(
$this->queue_table,
[
'status' => 'completed',
'completed_at' => current_time('mysql')
],
['job_id' => $job['job_id']]
);
} catch (Exception $e) {
// 标记为失败
$wpdb->update(
$this->queue_table,
[
'status' => $job['attempts'] + 1 >= $job['max_attempts'] ? 'failed' : 'pending',
'error_message' => $e->getMessage()
],
['job_id' => $job['job_id']]
);
error_log("队列任务处理失败: {$e->getMessage()}");
}
}
/**
* 处理库存同步任务
*/
private function process_inventory_sync($job) {
$sync_system = new MultiChannelInventorySync();
if ($job['channel_name']) {
// 同步特定渠道
$sync_system->sync_channel_inventory($job['product_id'], $job['channel_name']);
} else {
// 同步所有渠道
$sync_system->sync_product($job['product_id']);
}
}
}
/**
* WordPress定时任务处理器
*/
class InventoryCronManager {
/**
* 设置定时任务
*/
public function setup_cron_schedules() {
// 每5分钟处理一次队列
if (!wp_next_scheduled('process_inventory_queue')) {
wp_schedule_event(time(), 'five_minutes', 'process_inventory_queue');
}
// 每小时检查库存健康
if (!wp_next_scheduled('check_inventory_health')) {
wp_schedule_event(time(), 'hourly', 'check_inventory_health');
}
// 每天凌晨执行完整同步
if (!wp_next_scheduled('full_inventory_sync')) {
wp_schedule_event(strtotime('02:00:00'), 'daily', 'full_inventory_sync');
}
}
/**
* 添加自定义时间间隔
*/
public function add_cron_intervals($schedules) {
$schedules['five_minutes'] = [
'interval' => 300,
'display' => __('每5分钟')
];
$schedules['ten_minutes'] = [
'interval' => 600,
'display' => __('每10分钟')
];
return $schedules;
}
}
// 注册定时任务
add_filter('cron_schedules', [new InventoryCronManager(), 'add_cron_intervals']);
add_action('init', [new InventoryCronManager(), 'setup_cron_schedules']);
// 队列处理钩子
add_action('process_inventory_queue', function() {
$queue = new InventorySyncQueue();
$queue->process_queue(20); // 每次处理20个任务
});
// 库存健康检查
add_action('check_inventory_health', function() {
$monitor = new InventoryMonitor();
$monitor->check_low_stock();
$monitor->check_sync_health();
});
// 完整同步
add_action('full_inventory_sync', function() {
$sync_system = new MultiChannelInventorySync();
$sync_system->sync_all_channels();
});
## 错误处理与日志系统
### 增强的错误处理器
/**
- 增强的错误处理与日志系统
*/
class InventoryErrorHandler {
private $log_table;
private $error_notification_email;
public function __construct() {
global $wpdb;
$this->log_table = $wpdb->prefix . 'flexible_inventory_error_logs';
$this->error_notification_email = get_option('inventory_error_email');
}
/**
* 记录错误
*/
public function log_error($error_type, $message, $context = null, $severity = 'error') {
global $wpdb;
$data = [
'error_type' => $error_type,
'message' => $message,
'context' => $context ? json_encode($context) : null,
'severity' => $severity,
'server_data' => json_encode([
'request_uri' => $_SERVER['REQUEST_URI'] ?? '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? ''
]),
'created_at' => current_time('mysql')
];
$wpdb->insert($this->log_table, $data);
// 如果是严重错误,发送通知
if ($severity === 'critical' && $this->error_notification_email) {
$this->send_error_notification($error_type, $message, $context);
}
// 同时写入WordPress错误日志
error_log("[Inventory Error] {$error_type}: {$message}");
return $wpdb->insert_id;
}
/**
* 发送错误通知
*/
private function send_error_notification($error_type, $message, $context) {
$subject = "库存系统错误: {$error_type}";
$body = "错误类型: {$error_type}n";
$body .= "错误信息: {$message}n";
$body .= "发生时间: " . current_time('mysql') . "n";
$body .= "上下文: " . json_encode($context, JSON_PRETTY_PRINT) . "n";
$body .= "n请及时处理。n";
wp_mail($this->error_notification_email, $subject, $body);
}
/**
* 获取错误统计
*/
public function get_error_stats($hours = 24) {
global $wpdb;
return $wpdb->get_results(
$wpdb->prepare(
"SELECT
error_type,
severity,
COUNT(*) as count,
MIN(created_at) as first_occurrence,
MAX(created_at) as last_occurrence
FROM {$this->log_table}
WHERE created_at >= DATE_SUB(NOW(), INTERVAL %d HOUR)
GROUP BY error_type, severity
ORDER BY count DESC",
$hours
),
ARRAY_A
);
}
/**
* 自动重试机制
*/
public function with_retry(callable $function, $max_attempts = 3, $delay = 1000) {
$attempts = 0;
while ($attempts < $max_attempts) {
try {
return $function();
} catch (Exception $e) {
$attempts++;
if ($attempts >= $max_attempts) {
$this->log_error(
'retry_exhausted',
"重试{$max_attempts}次后仍然失败",
[
'error' => $e->getMessage(),
'attempts' => $attempts
],
'critical'
);
throw $e;
}
// 记录重试
$this->log_error(
'retry_attempt',
"第{$attempts}次重试失败",
[
'error' => $e->getMessage(),
'next_delay_ms' => $delay * $attempts
],
'warning'
);
// 指数退避延迟
usleep($delay * $attempts * 1000);
}
}
}
}
/**
- 库存API异常类
*/
class InventoryException extends Exception {
private $error_code;
private $additional_data;
public function __construct($message, $error_code = 'INVENTORY_ERROR', $additional_data = null, $previous = null) {
parent::__construct($message, 0, $previous);
$this->error_code = $error_code;
$this->additional_data = $additional_data;
}


