首页 / 教程文章 / WordPress柔性供应链中的实时库存同步接口开发详解

WordPress柔性供应链中的实时库存同步接口开发详解

WordPress柔性供应链中的实时库存同步接口开发详解

引言:柔性供应链与实时库存同步的重要性

在当今电子商务快速发展的时代,柔性供应链已成为企业保持竞争力的关键。对于使用WordPress构建的电商网站而言,实现实时库存同步不仅能避免超卖问题,还能提升客户体验和运营效率。本文将深入探讨如何在WordPress中开发一个高效的实时库存同步接口,连接多个供应商、仓库和销售渠道,构建真正的柔性供应链系统。

系统架构设计

整体架构概述

我们的实时库存同步系统将采用以下架构:

  • WordPress作为核心电商平台
  • REST API作为数据交换接口
  • 消息队列处理异步任务
  • 数据库存储库存快照和变更日志
  • 外部系统通过Webhook或API调用进行集成

数据库设计

/**
 * 库存同步系统数据库表结构
 * 需要添加到WordPress数据库中的自定义表
 */

// 创建库存主表
CREATE TABLE wp_inventory_master (
    id INT AUTO_INCREMENT PRIMARY KEY,
    product_id BIGINT(20) NOT NULL,  // 关联WordPress产品ID
    sku VARCHAR(100) NOT NULL,       // 产品SKU
    warehouse_id INT NOT NULL,       // 仓库ID
    current_stock INT DEFAULT 0,     // 当前库存
    reserved_stock INT DEFAULT 0,    // 预留库存
    available_stock INT DEFAULT 0,   // 可用库存
    low_stock_threshold INT DEFAULT 5, // 低库存阈值
    last_synced TIMESTAMP DEFAULT CURRENT_TIMESTAMP, // 最后同步时间
    UNIQUE KEY product_warehouse (product_id, warehouse_id)
);

// 创建库存变更日志表
CREATE TABLE wp_inventory_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    inventory_id INT NOT NULL,        // 关联库存记录ID
    change_type ENUM('sale', 'restock', 'adjustment', 'sync') NOT NULL,
    previous_stock INT NOT NULL,      // 变更前库存
    new_stock INT NOT NULL,           // 变更后库存
    quantity_changed INT NOT NULL,    // 变更数量
    source VARCHAR(100),              // 变更来源
    reference_id VARCHAR(100),        // 参考ID(如订单号)
    notes TEXT,                       // 备注
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (inventory_id) REFERENCES wp_inventory_master(id)
);

// 创建仓库信息表
CREATE TABLE wp_warehouses (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(200) NOT NULL,       // 仓库名称
    code VARCHAR(50) NOT NULL,        // 仓库代码
    location VARCHAR(500),            // 仓库地址
    is_active TINYINT(1) DEFAULT 1,   // 是否激活
    priority INT DEFAULT 1,           // 优先级(用于分配策略)
    api_endpoint VARCHAR(500),        // 仓库API端点
    api_key VARCHAR(500),             // API密钥
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

核心接口开发

REST API端点设计

/**
 * WordPress实时库存同步REST API接口
 * 注册自定义REST API路由和端点
 */

add_action('rest_api_init', function () {
    
    // 获取库存信息端点
    register_rest_route('inventory/v1', '/stock/(?P<sku>[a-zA-Z0-9-]+)', [
        'methods' => 'GET',
        'callback' => 'get_inventory_by_sku',
        'permission_callback' => 'inventory_api_permission_check',
        'args' => [
            'sku' => [
                'required' => true,
                'validate_callback' => function($param) {
                    return is_string($param) && !empty($param);
                }
            ],
            'warehouse_id' => [
                'required' => false,
                'default' => 0
            ]
        ]
    ]);
    
    // 更新库存端点
    register_rest_route('inventory/v1', '/stock/update', [
        'methods' => 'POST',
        'callback' => 'update_inventory',
        'permission_callback' => 'inventory_api_permission_check'
    ]);
    
    // 批量同步端点
    register_rest_route('inventory/v1', '/stock/bulk-sync', [
        'methods' => 'POST',
        'callback' => 'bulk_sync_inventory',
        'permission_callback' => 'inventory_api_permission_check'
    ]);
    
    // 库存变更历史端点
    register_rest_route('inventory/v1', '/stock/history/(?P<product_id>d+)', [
        'methods' => 'GET',
        'callback' => 'get_inventory_history',
        'permission_callback' => 'inventory_api_permission_check'
    ]);
});

/**
 * API权限检查
 */
function inventory_api_permission_check($request) {
    // 方法1:使用API密钥验证
    $api_key = $request->get_header('X-API-Key');
    $valid_keys = get_option('inventory_api_keys', []);
    
    if (in_array($api_key, $valid_keys)) {
        return true;
    }
    
    // 方法2:使用JWT令牌验证(可选)
    $auth_header = $request->get_header('Authorization');
    if ($auth_header && strpos($auth_header, 'Bearer ') === 0) {
        $token = substr($auth_header, 7);
        return validate_jwt_token($token);
    }
    
    // 方法3:WordPress用户权限验证
    if (current_user_can('manage_woocommerce')) {
        return true;
    }
    
    return new WP_Error('rest_forbidden', '无权访问库存API', ['status' => 403]);
}

库存同步核心逻辑

/**
 * 库存同步管理器类
 * 处理所有库存相关的业务逻辑
 */
class Inventory_Sync_Manager {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
    }
    
    /**
     * 根据SKU获取库存信息
     * @param string $sku 产品SKU
     * @param int $warehouse_id 仓库ID(0表示所有仓库)
     * @return array 库存信息
     */
    public function get_stock_by_sku($sku, $warehouse_id = 0) {
        $table_name = $this->db->prefix . 'inventory_master';
        
        if ($warehouse_id > 0) {
            // 获取特定仓库的库存
            $query = $this->db->prepare(
                "SELECT * FROM $table_name WHERE sku = %s AND warehouse_id = %d",
                $sku, $warehouse_id
            );
        } else {
            // 获取所有仓库的库存汇总
            $query = $this->db->prepare(
                "SELECT 
                    product_id,
                    sku,
                    SUM(current_stock) as total_stock,
                    SUM(reserved_stock) as total_reserved,
                    SUM(available_stock) as total_available,
                    GROUP_CONCAT(warehouse_id) as warehouse_ids
                 FROM $table_name 
                 WHERE sku = %s 
                 GROUP BY product_id, sku",
                $sku
            );
        }
        
        $result = $this->db->get_row($query, ARRAY_A);
        
        if (!$result) {
            return $this->create_error_response('库存记录不存在');
        }
        
        return [
            'success' => true,
            'data' => $result,
            'timestamp' => current_time('mysql')
        ];
    }
    
    /**
     * 更新库存信息
     * @param array $data 库存更新数据
     * @return array 更新结果
     */
    public function update_stock($data) {
        // 验证必要参数
        $required_fields = ['sku', 'warehouse_id', 'quantity', 'change_type'];
        foreach ($required_fields as $field) {
            if (!isset($data[$field])) {
                return $this->create_error_response("缺少必要字段: $field");
            }
        }
        
        // 开始数据库事务
        $this->db->query('START TRANSACTION');
        
        try {
            $sku = sanitize_text_field($data['sku']);
            $warehouse_id = intval($data['warehouse_id']);
            $quantity = intval($data['quantity']);
            $change_type = sanitize_text_field($data['change_type']);
            $source = isset($data['source']) ? sanitize_text_field($data['source']) : 'api';
            $reference_id = isset($data['reference_id']) ? sanitize_text_field($data['reference_id']) : '';
            
            // 获取当前库存记录
            $table_name = $this->db->prefix . 'inventory_master';
            $inventory = $this->db->get_row(
                $this->db->prepare(
                    "SELECT * FROM $table_name WHERE sku = %s AND warehouse_id = %d",
                    $sku, $warehouse_id
                ),
                ARRAY_A
            );
            
            if (!$inventory) {
                // 如果库存记录不存在,尝试创建(需要产品ID)
                $product_id = $this->get_product_id_by_sku($sku);
                if (!$product_id) {
                    throw new Exception("找不到SKU对应的产品: $sku");
                }
                
                $inventory = [
                    'product_id' => $product_id,
                    'sku' => $sku,
                    'warehouse_id' => $warehouse_id,
                    'current_stock' => 0,
                    'reserved_stock' => 0,
                    'available_stock' => 0
                ];
                
                $this->db->insert($table_name, $inventory);
                $inventory['id'] = $this->db->insert_id;
            }
            
            // 计算新库存值
            $previous_stock = intval($inventory['current_stock']);
            $new_stock = $this->calculate_new_stock($previous_stock, $quantity, $change_type);
            
            // 更新库存主表
            $update_data = [
                'current_stock' => $new_stock,
                'available_stock' => $this->calculate_available_stock($new_stock, $inventory['reserved_stock']),
                'last_synced' => current_time('mysql')
            ];
            
            $this->db->update(
                $table_name,
                $update_data,
                ['id' => $inventory['id']]
            );
            
            // 记录库存变更日志
            $this->log_inventory_change([
                'inventory_id' => $inventory['id'],
                'change_type' => $change_type,
                'previous_stock' => $previous_stock,
                'new_stock' => $new_stock,
                'quantity_changed' => $quantity,
                'source' => $source,
                'reference_id' => $reference_id,
                'notes' => isset($data['notes']) ? sanitize_textarea_field($data['notes']) : ''
            ]);
            
            // 检查低库存并触发通知
            $this->check_low_stock($inventory['id'], $new_stock, $inventory['low_stock_threshold']);
            
            // 同步到WooCommerce产品库存(如果适用)
            if (class_exists('WooCommerce')) {
                $this->sync_to_woocommerce($inventory['product_id']);
            }
            
            // 提交事务
            $this->db->query('COMMIT');
            
            return [
                'success' => true,
                'message' => '库存更新成功',
                'data' => [
                    'sku' => $sku,
                    'warehouse_id' => $warehouse_id,
                    'previous_stock' => $previous_stock,
                    'new_stock' => $new_stock,
                    'change_type' => $change_type
                ]
            ];
            
        } catch (Exception $e) {
            // 回滚事务
            $this->db->query('ROLLBACK');
            return $this->create_error_response("库存更新失败: " . $e->getMessage());
        }
    }
    
    /**
     * 计算新库存值
     */
    private function calculate_new_stock($current_stock, $quantity, $change_type) {
        switch ($change_type) {
            case 'sale':
            case 'deduction':
                return max(0, $current_stock - $quantity);
            case 'restock':
            case 'addition':
                return $current_stock + $quantity;
            case 'adjustment':
                return $quantity; // 直接设置为指定值
            default:
                throw new Exception("不支持的库存变更类型: $change_type");
        }
    }
    
    /**
     * 记录库存变更日志
     */
    private function log_inventory_change($log_data) {
        $table_name = $this->db->prefix . 'inventory_log';
        $this->db->insert($table_name, $log_data);
    }
    
    /**
     * 同步到WooCommerce
     */
    private function sync_to_woocommerce($product_id) {
        // 计算所有仓库的总可用库存
        $table_name = $this->db->prefix . 'inventory_master';
        $total_stock = $this->db->get_var(
            $this->db->prepare(
                "SELECT SUM(available_stock) FROM $table_name WHERE product_id = %d",
                $product_id
            )
        );
        
        // 更新WooCommerce产品库存
        update_post_meta($product_id, '_stock', intval($total_stock));
        update_post_meta($product_id, '_manage_stock', 'yes');
        
        // 更新库存状态
        $stock_status = (intval($total_stock) > 0) ? 'instock' : 'outofstock';
        update_post_meta($product_id, '_stock_status', $stock_status);
        
        // 清除产品缓存
        wc_delete_product_transients($product_id);
    }
}

异步处理与消息队列

/**
 * 库存同步消息队列处理器
 * 使用WordPress Cron或外部队列系统处理异步任务
 */
class Inventory_Queue_Processor {
    
    /**
     * 初始化队列处理器
     */
    public function init() {
        // 注册定时任务
        add_action('inventory_sync_cron', [$this, 'process_sync_queue']);
        
        // 添加自定义Cron间隔
        add_filter('cron_schedules', [$this, 'add_cron_intervals']);
        
        // 安排定时任务(如果尚未安排)
        if (!wp_next_scheduled('inventory_sync_cron')) {
            wp_schedule_event(time(), 'every_5_minutes', 'inventory_sync_cron');
        }
    }
    
    /**
     * 添加自定义Cron间隔
     */
    public function add_cron_intervals($schedules) {
        $schedules['every_5_minutes'] = [
            'interval' => 300, // 5分钟
            'display' => __('每5分钟')
        ];
        
        $schedules['every_15_minutes'] = [
            'interval' => 900, // 15分钟
            'display' => __('每15分钟')
        ];
        
        return $schedules;
    }
    
    /**
     * 处理同步队列
     */
    public function process_sync_queue() {
        global $wpdb;
        
        // 获取待处理的同步任务
        $queue_table = $wpdb->prefix . 'inventory_sync_queue';
        $pending_tasks = $wpdb->get_results(
            "SELECT * FROM $queue_table 
             WHERE status = 'pending' 
             AND attempts < 3 
             ORDER BY priority DESC, created_at ASC 
             LIMIT 50"
        );
        
        if (empty($pending_tasks)) {
            return;
        }
        
        $sync_manager = new Inventory_Sync_Manager();
        
        foreach ($pending_tasks as $task) {
            try {
                // 更新任务状态为处理中
                $wpdb->update(
                    $queue_table,
                    ['status' => 'processing', 'started_at' => current_time('mysql')],
                    ['id' => $task->id]
                );
                
                // 处理同步任务
                $task_data = json_decode($task->task_data, true);
                $result = $sync_manager->update_stock($task_data);
                
                if ($result['success']) {
                    // 标记任务为完成
                    $wpdb->update(
                        $queue_table,
                        [
                            'status' => 'completed',
                            'completed_at' => current_time('mysql'),
                            'result' => json_encode($result)
                        ],
                        ['id' => $task->id]
                    );
                } else {
                    // 标记任务为失败
                    $wpdb->update(
                        $queue_table,
                        [
                            'status' => 'failed',
                            'attempts' => $task->attempts + 1,
                            'last_error' => $result['message'],
                            'next_retry' => date('Y-m-d H:i:s', time() + 300) // 5分钟后重试
                        ],
                        ['id' => $task->id]
                    );
                }
                
            } catch (Exception $e) {
                // 记录异常
                error_log("库存同步任务处理失败: " . $e->getMessage());
                
                $wpdb->update(
                    $queue_table,
                    [
                        'status' => 'failed',
                        'attempts' => $task->attempts + 1,
                        'last_error' => $e->getMessage()
                    ],
                    ['id' => $task->id]
                );
            }
        }
    }
    
    /**
     * 添加同步任务到队列
     */
    public function add_to_queue($task_data, $priority = 1) {
        global $wpdb;
        
        $queue_table = $wpdb->prefix . 'inventory_sync_queue';
        
        $wpdb->insert($queue_table, [
            'task_type' => 'inventory_sync',
            'task_data' => json_encode($task_data),
            'priority' => $priority,
            'status' => 'pending',
            'created_at' => current_time('mysql')
        ]);
        
        return $wpdb->insert_id;
    }
}

安全与性能优化

API安全措施

/**

安全与性能优化

API安全措施

/**
 * 库存API安全增强类
 * 提供多种安全防护机制
 */
class Inventory_API_Security {
    
    /**
     * 验证API请求签名
     * 防止请求被篡改
     */
    public static function verify_request_signature($request) {
        $api_key = $request->get_header('X-API-Key');
        $timestamp = $request->get_header('X-Timestamp');
        $signature = $request->get_header('X-Signature');
        
        // 验证时间戳(防止重放攻击)
        if (abs(time() - intval($timestamp)) > 300) { // 5分钟有效期
            return new WP_Error('invalid_timestamp', '请求已过期', ['status' => 401]);
        }
        
        // 获取请求体
        $body = $request->get_body();
        $method = $request->get_method();
        $path = $request->get_route();
        
        // 生成签名
        $secret_key = self::get_secret_key($api_key);
        $signature_string = $method . $path . $timestamp . $body;
        $expected_signature = hash_hmac('sha256', $signature_string, $secret_key);
        
        // 验证签名
        if (!hash_equals($expected_signature, $signature)) {
            return new WP_Error('invalid_signature', '签名验证失败', ['status' => 401]);
        }
        
        return true;
    }
    
    /**
     * 请求频率限制
     */
    public static function rate_limit_check($api_key, $endpoint) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'api_rate_limits';
        $current_time = current_time('mysql');
        $window_start = date('Y-m-d H:i:s', strtotime('-1 minute'));
        
        // 获取最近一分钟内的请求次数
        $count = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $table_name 
             WHERE api_key = %s 
             AND endpoint = %s 
             AND request_time > %s",
            $api_key, $endpoint, $window_start
        ));
        
        // 限制规则:每分钟最多60次请求
        if ($count >= 60) {
            return new WP_Error('rate_limit_exceeded', '请求频率过高', ['status' => 429]);
        }
        
        // 记录本次请求
        $wpdb->insert($table_name, [
            'api_key' => $api_key,
            'endpoint' => $endpoint,
            'request_time' => $current_time,
            'ip_address' => self::get_client_ip()
        ]);
        
        return true;
    }
    
    /**
     * SQL注入防护
     */
    public static function sanitize_inventory_data($data) {
        $sanitized = [];
        
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $sanitized[$key] = self::sanitize_inventory_data($value);
            } else {
                // 根据字段类型进行不同的清理
                switch ($key) {
                    case 'sku':
                    case 'source':
                    case 'reference_id':
                        $sanitized[$key] = sanitize_text_field($value);
                        break;
                    case 'notes':
                        $sanitized[$key] = sanitize_textarea_field($value);
                        break;
                    case 'quantity':
                    case 'warehouse_id':
                    case 'product_id':
                        $sanitized[$key] = intval($value);
                        break;
                    default:
                        $sanitized[$key] = sanitize_text_field($value);
                }
            }
        }
        
        return $sanitized;
    }
}

性能优化策略

/**
 * 库存系统性能优化类
 * 实现缓存、索引优化等策略
 */
class Inventory_Performance_Optimizer {
    
    private static $cache_group = 'inventory_cache';
    
    /**
     * 获取带缓存的库存信息
     */
    public static function get_cached_inventory($sku, $warehouse_id = 0) {
        $cache_key = "inventory_{$sku}_{$warehouse_id}";
        
        // 尝试从缓存获取
        $cached = wp_cache_get($cache_key, self::$cache_group);
        
        if ($cached !== false) {
            return $cached;
        }
        
        // 缓存未命中,从数据库获取
        global $wpdb;
        $table_name = $wpdb->prefix . 'inventory_master';
        
        if ($warehouse_id > 0) {
            $query = $wpdb->prepare(
                "SELECT * FROM $table_name 
                 WHERE sku = %s AND warehouse_id = %d",
                $sku, $warehouse_id
            );
        } else {
            $query = $wpdb->prepare(
                "SELECT 
                    product_id,
                    sku,
                    SUM(current_stock) as total_stock,
                    SUM(available_stock) as total_available
                 FROM $table_name 
                 WHERE sku = %s 
                 GROUP BY product_id, sku",
                $sku
            );
        }
        
        $result = $wpdb->get_row($query, ARRAY_A);
        
        // 存入缓存,有效期60秒
        wp_cache_set($cache_key, $result, self::$cache_group, 60);
        
        return $result;
    }
    
    /**
     * 批量获取库存信息(减少数据库查询)
     */
    public static function batch_get_inventory($skus, $warehouse_id = 0) {
        if (empty($skus)) {
            return [];
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'inventory_master';
        
        // 构建IN查询
        $placeholders = array_fill(0, count($skus), '%s');
        $placeholder_string = implode(',', $placeholders);
        
        if ($warehouse_id > 0) {
            $query = $wpdb->prepare(
                "SELECT * FROM $table_name 
                 WHERE sku IN ($placeholder_string) 
                 AND warehouse_id = %d",
                array_merge($skus, [$warehouse_id])
            );
        } else {
            $query = $wpdb->prepare(
                "SELECT 
                    sku,
                    SUM(current_stock) as total_stock,
                    SUM(available_stock) as total_available
                 FROM $table_name 
                 WHERE sku IN ($placeholder_string)
                 GROUP BY sku",
                $skus
            );
        }
        
        $results = $wpdb->get_results($query, ARRAY_A);
        
        // 转换为以SKU为键的数组
        $inventory_map = [];
        foreach ($results as $row) {
            $inventory_map[$row['sku']] = $row;
        }
        
        return $inventory_map;
    }
    
    /**
     * 数据库索引优化建议
     */
    public static function optimize_database_indexes() {
        global $wpdb;
        
        $index_queries = [
            // 为库存主表添加复合索引
            "ALTER TABLE {$wpdb->prefix}inventory_master 
             ADD INDEX idx_sku_warehouse (sku, warehouse_id)",
            
            "ALTER TABLE {$wpdb->prefix}inventory_master 
             ADD INDEX idx_product_warehouse (product_id, warehouse_id)",
            
            "ALTER TABLE {$wpdb->prefix}inventory_master 
             ADD INDEX idx_last_synced (last_synced)",
            
            // 为日志表添加索引
            "ALTER TABLE {$wpdb->prefix}inventory_log 
             ADD INDEX idx_inventory_id (inventory_id)",
            
            "ALTER TABLE {$wpdb->prefix}inventory_log 
             ADD INDEX idx_created_at (created_at)",
            
            "ALTER TABLE {$wpdb->prefix}inventory_log 
             ADD INDEX idx_change_type (change_type)",
        ];
        
        foreach ($index_queries as $query) {
            $wpdb->query($query);
        }
    }
    
    /**
     * 清理历史数据
     */
    public static function cleanup_old_data($days_to_keep = 90) {
        global $wpdb;
        
        $cutoff_date = date('Y-m-d H:i:s', strtotime("-$days_to_keep days"));
        
        // 清理旧的库存日志
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->prefix}inventory_log 
             WHERE created_at < %s",
            $cutoff_date
        ));
        
        // 清理旧的API请求日志
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->prefix}api_rate_limits 
             WHERE request_time < %s",
            $cutoff_date
        ));
        
        // 优化表
        $tables = [
            'inventory_log',
            'inventory_master',
            'api_rate_limits',
            'inventory_sync_queue'
        ];
        
        foreach ($tables as $table) {
            $wpdb->query("OPTIMIZE TABLE {$wpdb->prefix}$table");
        }
    }
}

外部系统集成

Webhook处理器

/**
 * Webhook处理器
 * 用于接收外部系统的库存变更通知
 */
class Inventory_Webhook_Handler {
    
    /**
     * 注册Webhook端点
     */
    public static function register_webhooks() {
        add_action('rest_api_init', function() {
            // 接收外部系统Webhook
            register_rest_route('inventory/v1', '/webhook/(?P<provider>[a-zA-Z0-9_-]+)', [
                'methods' => 'POST',
                'callback' => [__CLASS__, 'handle_webhook'],
                'permission_callback' => [__CLASS__, 'verify_webhook_signature']
            ]);
        });
    }
    
    /**
     * 处理Webhook请求
     */
    public static function handle_webhook($request) {
        $provider = $request->get_param('provider');
        $payload = $request->get_json_params();
        
        // 根据提供商处理不同的数据格式
        switch ($provider) {
            case 'warehouse_system_a':
                return self::process_warehouse_a_webhook($payload);
            case 'erp_system_b':
                return self::process_erp_b_webhook($payload);
            case 'supplier_portal_c':
                return self::process_supplier_c_webhook($payload);
            default:
                return new WP_Error('invalid_provider', '不支持的提供商', ['status' => 400]);
        }
    }
    
    /**
     * 处理仓库系统A的Webhook
     */
    private static function process_warehouse_a_webhook($payload) {
        // 验证必要字段
        $required_fields = ['event_type', 'data', 'timestamp'];
        foreach ($required_fields as $field) {
            if (!isset($payload[$field])) {
                return new WP_Error('missing_field', "缺少字段: $field", ['status' => 400]);
            }
        }
        
        $event_type = $payload['event_type'];
        $data = $payload['data'];
        
        switch ($event_type) {
            case 'stock_update':
                return self::process_stock_update($data, 'warehouse_system_a');
            case 'stock_adjustment':
                return self::process_stock_adjustment($data, 'warehouse_system_a');
            case 'inventory_sync':
                return self::process_inventory_sync($data, 'warehouse_system_a');
            default:
                return new WP_Error('invalid_event', '不支持的事件类型', ['status' => 400]);
        }
    }
    
    /**
     * 处理库存更新
     */
    private static function process_stock_update($data, $source) {
        $sync_manager = new Inventory_Sync_Manager();
        
        // 转换数据格式
        $inventory_data = [
            'sku' => $data['product_code'],
            'warehouse_id' => self::get_warehouse_id_by_code($data['warehouse_code']),
            'quantity' => $data['quantity'],
            'change_type' => $data['change_type'],
            'source' => $source,
            'reference_id' => $data['transaction_id'],
            'notes' => isset($data['notes']) ? $data['notes'] : ''
        ];
        
        // 更新库存
        $result = $sync_manager->update_stock($inventory_data);
        
        if ($result['success']) {
            // 发送确认响应
            return [
                'success' => true,
                'message' => '库存更新成功',
                'processed_at' => current_time('mysql'),
                'reference_id' => $data['transaction_id']
            ];
        } else {
            return new WP_Error('update_failed', $result['message'], ['status' => 500]);
        }
    }
    
    /**
     * 验证Webhook签名
     */
    public static function verify_webhook_signature($request) {
        $provider = $request->get_param('provider');
        $signature = $request->get_header('X-Webhook-Signature');
        
        // 获取提供商的密钥
        $webhook_secret = get_option("inventory_webhook_secret_{$provider}");
        
        if (!$webhook_secret) {
            return new WP_Error('no_secret', '未配置Webhook密钥', ['status' => 401]);
        }
        
        // 计算签名
        $payload = $request->get_body();
        $expected_signature = hash_hmac('sha256', $payload, $webhook_secret);
        
        // 验证签名
        if (!hash_equals($expected_signature, $signature)) {
            return new WP_Error('invalid_signature', '签名验证失败', ['status' => 401]);
        }
        
        return true;
    }
}

外部API客户端

/**
 * 外部API客户端
 * 用于主动从外部系统拉取库存数据
 */
class External_API_Client {
    
    /**
     * 从仓库系统同步库存
     */
    public static function sync_from_warehouse($warehouse_id) {
        $warehouse = self::get_warehouse_info($warehouse_id);
        
        if (!$warehouse || !$warehouse['is_active']) {
            return new WP_Error('invalid_warehouse', '仓库不存在或未激活', ['status' => 400]);
        }
        
        // 构建API请求
        $api_url = $warehouse['api_endpoint'] . '/inventory';
        $api_key = $warehouse['api_key'];
        
        $response = wp_remote_get($api_url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $api_key,
                'Accept' => 'application/json'
            ],
            'timeout' => 30
        ]);
        
        if (is_wp_error($response)) {
            return $response;
        }
        
        $status_code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        if ($status_code !== 200) {
            return new WP_Error('api_error', "API请求失败: {$status_code}", ['status' => $status_code]);
        }
        
        // 处理同步数据
        return self::process_sync_data($data, $warehouse_id);
    }
    
    /**
     * 处理同步数据
     */
    private static function process_sync_data($data, $warehouse_id) {
        $sync_manager = new Inventory_Sync_Manager();
        $results = [
            'success' => 0,
            'failed' => 0,
            'errors' => []
        ];
        
        foreach ($data['inventory_items'] as $item) {
            try {
                $inventory_data = [
                    'sku' => $item['sku'],
                    'warehouse_id' => $warehouse_id,
                    'quantity' => $item['quantity'],
                    'change_type' => 'sync',
                    'source' => 'warehouse_sync',
                    'reference_id' => 'sync_batch_' . time()
                ];
                
                $result = $sync_manager->update_stock($inventory_data);
                
                if ($result['success']) {
                    $results['success']++;
                } else {
                    $results['failed']++;
                    $results['errors'][] = [
                        'sku' => $item['sku'],
                        'error' => $result['message']
                    ];
                }
            } catch (Exception $e) {
                $results['failed']++;
                $results['errors'][] = [
                    'sku' => $item['sku'],
                    'error' => $e->getMessage()
                ];
            }
        }
        
        // 记录同步日志
        self::log_sync_result($warehouse_id, $results);
        
        return $results;
    }
    
    /**
     * 批量同步多个仓库
     */
    public static function batch_sync_warehouses($warehouse_ids = []) {
        if (empty($warehouse_ids)) {
            // 获取所有激活的仓库
            global $wpdb;
            $warehouse_ids = $wpdb->get_col(
                "SELECT id FROM {$wpdb->prefix}warehouses WHERE is_active = 1"
            );
        }
        
        $all_results = [];
        
        foreach ($warehouse_ids as $warehouse_id) {
            $result = self::sync_from_warehouse($warehouse_id);
            $all_results[$warehouse_id] = $result;
            
            // 避免请求过于频繁
            sleep(1);
        }
        
        return $all_results;
    }
}

监控与报警系统

/**
 * 库存监控与报警系统
 */
class Inventory_Monitor {
    
    /**
     * 检查低库存并发送报警
     */
    public static function check_low_stock_alerts() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'inventory_master';
        
        // 查找低于阈值的库存
        $low_stock_items = $wpdb->get_results(
            "SELECT im.*, p.post_title as product_name
             FROM $table_name im
             LEFT JOIN {$wpdb->posts} p ON im.product_id = p.ID
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6293.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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