首页 / 教程文章 / WordPress多节点柔性供应链插件开发实战教程

WordPress多节点柔性供应链插件开发实战教程

WordPress多节点柔性供应链插件开发实战教程

引言:为什么需要柔性供应链插件

在当今电商竞争激烈的环境中,传统的单一供应链系统已无法满足企业的多样化需求。特别是对于使用WordPress搭建电商网站的中小企业来说,一个能够灵活调配多个供应商、仓库和物流节点的系统至关重要。本文将带您一步步开发一个WordPress多节点柔性供应链插件,实现库存智能分配、供应商自动选择和物流优化等功能。

环境准备与插件基础结构

首先,我们需要创建插件的基础结构。在WordPress的wp-content/plugins/目录下创建新文件夹flexible-supply-chain

<?php
/**
 * Plugin Name: 柔性供应链管理系统
 * Plugin URI: https://yourwebsite.com/
 * Description: WordPress多节点柔性供应链管理插件
 * Version: 1.0.0
 * Author: Your Name
 * License: GPL v2 or later
 */

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

// 定义插件常量
define('FSC_VERSION', '1.0.0');
define('FSC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FSC_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
class FlexibleSupplyChain {
    
    private static $instance = null;
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->init_hooks();
    }
    
    private function init_hooks() {
        // 激活/停用钩子
        register_activation_hook(__FILE__, array($this, 'activate'));
        register_deactivation_hook(__FILE__, array($this, 'deactivate'));
        
        // 初始化
        add_action('init', array($this, 'init'));
        
        // 管理菜单
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // 加载脚本和样式
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    }
    
    public function activate() {
        $this->create_tables();
        $this->create_default_settings();
    }
    
    public function deactivate() {
        // 清理临时数据
    }
    
    public function init() {
        // 初始化代码
    }
    
    // 其他方法将在后续实现
}

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

数据库设计与表结构

柔性供应链系统需要存储供应商、仓库、库存和订单分配等信息。我们创建以下数据库表:

<?php
/**
 * 创建数据库表
 */
private function create_tables() {
    global $wpdb;
    
    $charset_collate = $wpdb->get_charset_collate();
    
    // 供应商表
    $suppliers_table = $wpdb->prefix . 'fsc_suppliers';
    $sql1 = "CREATE TABLE IF NOT EXISTS $suppliers_table (
        id INT(11) NOT NULL AUTO_INCREMENT,
        name VARCHAR(255) NOT NULL,
        code VARCHAR(50) NOT NULL UNIQUE,
        contact_person VARCHAR(100),
        email VARCHAR(100),
        phone VARCHAR(50),
        address TEXT,
        priority INT(11) DEFAULT 0,
        is_active TINYINT(1) DEFAULT 1,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id)
    ) $charset_collate;";
    
    // 仓库节点表
    $warehouses_table = $wpdb->prefix . 'fsc_warehouses';
    $sql2 = "CREATE TABLE IF NOT EXISTS $warehouses_table (
        id INT(11) NOT NULL AUTO_INCREMENT,
        name VARCHAR(255) NOT NULL,
        code VARCHAR(50) NOT NULL UNIQUE,
        supplier_id INT(11),
        location VARCHAR(255),
        latitude DECIMAL(10, 8),
        longitude DECIMAL(11, 8),
        capacity INT(11) DEFAULT 0,
        current_load INT(11) DEFAULT 0,
        lead_time INT(11) DEFAULT 1 COMMENT '交货时间(天)',
        shipping_cost DECIMAL(10, 2) DEFAULT 0,
        is_active TINYINT(1) DEFAULT 1,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        FOREIGN KEY (supplier_id) REFERENCES $suppliers_table(id) ON DELETE SET NULL
    ) $charset_collate;";
    
    // 库存表
    $inventory_table = $wpdb->prefix . 'fsc_inventory';
    $sql3 = "CREATE TABLE IF NOT EXISTS $inventory_table (
        id INT(11) NOT NULL AUTO_INCREMENT,
        product_id INT(11) NOT NULL COMMENT '关联WooCommerce产品ID',
        warehouse_id INT(11) NOT NULL,
        sku VARCHAR(100),
        quantity INT(11) DEFAULT 0,
        reserved_quantity INT(11) DEFAULT 0 COMMENT '已预订数量',
        safety_stock INT(11) DEFAULT 10 COMMENT '安全库存',
        reorder_point INT(11) DEFAULT 20 COMMENT '补货点',
        status ENUM('in_stock', 'low_stock', 'out_of_stock') DEFAULT 'in_stock',
        last_updated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY product_warehouse (product_id, warehouse_id),
        FOREIGN KEY (warehouse_id) REFERENCES $warehouses_table(id) ON DELETE CASCADE
    ) $charset_collate;";
    
    // 订单分配表
    $allocations_table = $wpdb->prefix . 'fsc_allocations';
    $sql4 = "CREATE TABLE IF NOT EXISTS $allocations_table (
        id INT(11) NOT NULL AUTO_INCREMENT,
        order_id INT(11) NOT NULL COMMENT 'WooCommerce订单ID',
        order_item_id INT(11) NOT NULL,
        product_id INT(11) NOT NULL,
        warehouse_id INT(11) NOT NULL,
        quantity INT(11) NOT NULL,
        allocation_type ENUM('auto', 'manual') DEFAULT 'auto',
        status ENUM('pending', 'confirmed', 'shipped', 'delivered') DEFAULT 'pending',
        estimated_ship_date DATE,
        actual_ship_date DATE,
        tracking_number VARCHAR(100),
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        FOREIGN KEY (warehouse_id) REFERENCES $warehouses_table(id) ON DELETE CASCADE
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql1);
    dbDelta($sql2);
    dbDelta($sql3);
    dbDelta($sql4);
    
    // 添加版本号到选项表,便于后续升级
    add_option('fsc_db_version', FSC_VERSION);
}
?>

智能库存分配算法实现

柔性供应链的核心是智能分配算法。以下是一个基于多因素决策的库存分配算法:

<?php
/**
 * 智能库存分配算法
 * @param int $product_id 产品ID
 * @param int $required_quantity 需求数量
 * @param array $customer_location 客户位置 [latitude, longitude]
 * @return array 分配结果
 */
public function allocate_inventory($product_id, $required_quantity, $customer_location = null) {
    global $wpdb;
    
    $allocations = array();
    $remaining_quantity = $required_quantity;
    
    // 获取所有有库存的仓库
    $inventory_table = $wpdb->prefix . 'fsc_inventory';
    $warehouses_table = $wpdb->prefix . 'fsc_warehouses';
    
    $query = $wpdb->prepare(
        "SELECT i.*, w.*, 
                (i.quantity - i.reserved_quantity) as available_quantity,
                w.shipping_cost,
                w.lead_time
         FROM $inventory_table i
         JOIN $warehouses_table w ON i.warehouse_id = w.id
         WHERE i.product_id = %d 
         AND (i.quantity - i.reserved_quantity) > 0
         AND w.is_active = 1
         ORDER BY w.priority DESC, 
                  (i.quantity - i.reserved_quantity) DESC",
        $product_id
    );
    
    $available_stock = $wpdb->get_results($query);
    
    // 如果没有库存,返回空数组
    if (empty($available_stock)) {
        return $allocations;
    }
    
    // 计算每个仓库的得分(多因素决策)
    $scored_warehouses = array();
    foreach ($available_stock as $stock) {
        $score = 0;
        
        // 因素1:库存充足度(30%权重)
        $availability_score = min(100, ($stock->available_quantity / $required_quantity) * 100);
        $score += $availability_score * 0.3;
        
        // 因素2:交货时间(25%权重)
        $lead_time_score = max(0, 100 - ($stock->lead_time * 10));
        $score += $lead_time_score * 0.25;
        
        // 因素3:运输成本(20%权重)
        $cost_score = max(0, 100 - ($stock->shipping_cost * 5));
        $score += $cost_score * 0.2;
        
        // 因素4:仓库负载率(15%权重)
        $load_ratio = $stock->current_load / max(1, $stock->capacity);
        $load_score = (1 - $load_ratio) * 100;
        $score += $load_score * 0.15;
        
        // 因素5:距离(如果提供了客户位置,10%权重)
        if ($customer_location && $stock->latitude && $stock->longitude) {
            $distance = $this->calculate_distance(
                $customer_location['latitude'],
                $customer_location['longitude'],
                $stock->latitude,
                $stock->longitude
            );
            $distance_score = max(0, 100 - ($distance * 0.1));
            $score += $distance_score * 0.1;
        }
        
        $scored_warehouses[] = array(
            'warehouse' => $stock,
            'score' => $score,
            'available_quantity' => $stock->available_quantity
        );
    }
    
    // 按得分排序
    usort($scored_warehouses, function($a, $b) {
        return $b['score'] <=> $a['score'];
    });
    
    // 分配库存
    foreach ($scored_warehouses as $scored) {
        if ($remaining_quantity <= 0) break;
        
        $warehouse = $scored['warehouse'];
        $allocate_quantity = min($scored['available_quantity'], $remaining_quantity);
        
        $allocations[] = array(
            'warehouse_id' => $warehouse->id,
            'warehouse_name' => $warehouse->name,
            'quantity' => $allocate_quantity,
            'lead_time' => $warehouse->lead_time,
            'shipping_cost' => $warehouse->shipping_cost,
            'score' => $scored['score']
        );
        
        $remaining_quantity -= $allocate_quantity;
    }
    
    // 如果还有剩余需求,尝试从低优先级仓库分配
    if ($remaining_quantity > 0) {
        // 这里可以添加备选分配逻辑
        error_log("库存不足: 产品{$product_id} 还需要{$remaining_quantity}件");
    }
    
    return $allocations;
}

/**
 * 计算两个坐标之间的距离(公里)
 * 使用Haversine公式
 */
private function calculate_distance($lat1, $lon1, $lat2, $lon2) {
    $earth_radius = 6371; // 地球半径,单位公里
    
    $lat1_rad = deg2rad($lat1);
    $lon1_rad = deg2rad($lon1);
    $lat2_rad = deg2rad($lat2);
    $lon2_rad = deg2rad($lon2);
    
    $delta_lat = $lat2_rad - $lat1_rad;
    $delta_lon = $lon2_rad - $lon1_rad;
    
    $a = sin($delta_lat/2) * sin($delta_lat/2) + 
         cos($lat1_rad) * cos($lat2_rad) * 
         sin($delta_lon/2) * sin($delta_lon/2);
    
    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    
    return $earth_radius * $c;
}
?>

WooCommerce订单集成与自动分配

将我们的供应链系统与WooCommerce订单系统集成:

<?php
/**
 * WooCommerce订单集成
 */
class FSC_WooCommerce_Integration {
    
    public function __construct() {
        // 订单状态变更钩子
        add_action('woocommerce_order_status_processing', array($this, 'process_order_allocation'), 10, 1);
        add_action('woocommerce_order_status_completed', array($this, 'update_inventory_after_shipment'), 10, 1);
        
        // 添加订单详情页的供应链信息
        add_action('woocommerce_order_details_after_order_table', array($this, 'display_supply_chain_info'), 10, 1);
        
        // 后台订单详情添加分配信息
        add_action('add_meta_boxes', array($this, 'add_order_meta_box'));
    }
    
    /**
     * 处理订单分配
     */
    public function process_order_allocation($order_id) {
        $order = wc_get_order($order_id);
        
        if (!$order) {
            return;
        }
        
        // 获取客户位置(如果有)
        $customer_location = $this->get_customer_location($order);
        
        // 遍历订单中的每个商品
        foreach ($order->get_items() as $item_id => $item) {
            $product_id = $item->get_product_id();
            $quantity = $item->get_quantity();
            
            // 调用智能分配算法
            $allocations = $this->allocate_inventory($product_id, $quantity, $customer_location);
            
            if (!empty($allocations)) {
                $this->save_allocations($order_id, $item_id, $product_id, $allocations);
                $this->reserve_inventory($allocations);
                
                // 更新订单备注
                $allocation_note = "库存已分配: ";
                foreach ($allocations as $alloc) {
                    $allocation_note .= "{$alloc['warehouse_name']}({$alloc['quantity']}件) ";
                }
                $order->add_order_note($allocation_note);
            } else {
                // 库存不足处理
                $order->add_order_note("库存不足,产品ID: {$product_id}");
                $order->update_status('on-hold', '等待库存补充');
            }
        }
    }
    
    /**
     * 保存分配记录到数据库
     */
    private function save_allocations($order_id, $item_id, $product_id, $allocations) {
        global $wpdb;
        $table = $wpdb->prefix . 'fsc_allocations';
        
        foreach ($allocations as $alloc) {
            $wpdb->insert(
                $table,
                array(
                    'order_id' => $order_id,
                    'order_item_id' => $item_id,
                    'product_id' => $product_id,
                    'warehouse_id' => $alloc['warehouse_id'],
                    'quantity' => $alloc['quantity'],
                    'allocation_type' => 'auto',
                    'status' => 'confirmed',
                    'estimated_ship_date' => date('Y-m-d', strtotime("+{$alloc['lead_time']} days"))
                ),
                array('%d', '%d', '%d', '%d', '%d', '%s', '%s', '%s')
            );
        }
    }
    
    /**
     * 预留库存
     */
    private function reserve_inventory($allocations) {
        global $wpdb;
        $table = $wpdb->prefix . 'fsc_inventory';
        
        foreach ($allocations as $alloc) {
            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE $table 
                     SET reserved_quantity = reserved_quantity + %d 
                     WHERE warehouse_id = %d",
                    $alloc['quantity'],
                    $alloc['warehouse_id']
                )
            );
        }
    }
    
    /**
     * 添加订单详情元框
     */
    public function add_order_meta_box() {
        add_meta_box(
            'fsc_order_allocation',
            '供应链分配信息',
            array($this, 'render_order_meta_box'),
            'shop_order',
            'side',
            'high'
        );
    }
    
    /**
     * 渲染订单元框内容
     */
    public function render_order_meta_box($post) {
        global $wpdb;
        $order_id = $post->ID;
        
        $allocations_table = $wpdb->prefix . 'fsc_allocations';
        $warehouses_table = $wpdb->prefix . 'fsc_warehouses';
        
        $allocations = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT a.*, w.name as warehouse_name 
                 FROM $allocations_table a
                 JOIN $warehouses_table w ON a.warehouse_id = w.id
                 WHERE a.order_id = %d",
                $order_id
            )
        );
        
        if ($allocations) {
            echo '<div class="fsc-allocation-info">';
            echo '<h4>库存分配详情:</h4>';
            echo '<ul>';
            foreach ($allocations as $alloc) {
                echo '<li>';
                echo "仓库: {$alloc->warehouse_name}<br>";
                echo "产品ID: {$alloc->product_id}<br>";
                echo "数量: {$alloc->quantity}<br>";
                echo "状态: {$alloc->status}<br>";
                echo "预计发货: " . ($alloc->estimated_ship_date ?: '未设置') . "<br>";
                if ($alloc->tracking_number) {
                    echo "物流单号: {$alloc->tracking_number}";
                }
                echo '</li>';
            }
            echo '</ul>';
            
            // 添加手动重新分配按钮
            echo '<button type="button" class="button button-secondary" id="reallocate-inventory">重新分配库存</button>';
            echo '</div>';
            
            // 添加JavaScript处理重新分配
            echo '<script>
            jQuery(document).ready(function($) {
                $("#reallocate-inventory").click(function() {
                    if (confirm("确定要重新分配库存吗?这将取消当前的分配并尝试新的分配策略。")) {
                        $.post(ajaxurl, {
                            action: "fsc_reallocate_order",
                            order_id: ' . $order_id . ',
                            nonce: "' . wp_create_nonce('fsc_reallocate') . '"
                        }, function(response) {
                            if (response.success) {
                                location.reload();
                            } else {
                                alert("重新分配失败: " + response.data);
                            }
                        });
                    }
                });
            });
            </script>';
        } else {
            echo '<p>暂无分配信息</p>';
            echo '<button type="button" class="button button-primary" id="allocate-inventory">分配库存</button>';
        }
    }
}
?>

管理界面与可视化仪表板

创建直观的管理界面,让用户可以轻松管理供应链节点:

<?php
/**
 * 供应链管理仪表板
 */
class FSC_Admin_Dashboard {
    
    public function __construct() {
        add_action('admin_menu', array($this, 'register_admin_pages'));
        add_action('admin_init', array($this, 'register_settings'));
        add_action('wp_ajax_fsc_get_dashboard_data', array($this, 'ajax_get_dashboard_data'));
    }
    
    /**
     * 注册管理页面
     */
    public function register_admin_pages() {
        // 主菜单
        add_menu_page(
            '柔性供应链',
            '供应链管理',
            'manage_options',
            'fsc-dashboard',
            array($this, 'render_dashboard'),
            'dashicons-networking',
            30
        );
        
        // 子菜单
        add_submenu_page(
            'fsc-dashboard',
            '仓库管理',
            '仓库节点',
            'manage_options',
            'fsc-warehouses',
            array($this, 'render_warehouses_page')
        );
        
        add_submenu_page(
            'fsc-dashboard',
            '供应商管理',
            '供应商',
            'manage_options',
            'fsc-suppliers',
            array($this, 'render_suppliers_page')
        );
        
        add_submenu_page(
            'fsc-dashboard',
            '库存监控',
            '库存监控',
            'manage_options',
            'fsc-inventory',
            array($this, 'render_inventory_page')
        );
        
        add_submenu_page(
            'fsc-dashboard',
            '分配记录',
            '分配记录',
            'manage_options',
            'fsc-allocations',
            array($this, 'render_allocations_page')
        );
        
        add_submenu_page(
            'fsc-dashboard',
            '系统设置',
            '系统设置',
            'manage_options',
            'fsc-settings',
            array($this, 'render_settings_page')
        );
    }
    
    /**
     * 渲染仪表板
     */
    public function render_dashboard() {
        ?>
        <div class="wrap fsc-dashboard">
            <h1>柔性供应链管理系统</h1>
            
            <div class="fsc-stats-row">
                <div class="fsc-stat-box">
                    <h3>活跃仓库</h3>
                    <div class="stat-number" id="active-warehouses">0</div>
                </div>
                
                <div class="fsc-stat-box">
                    <h3>总库存量</h3>
                    <div class="stat-number" id="total-inventory">0</div>
                </div>
                
                <div class="fsc-stat-box">
                    <h3>今日分配</h3>
                    <div class="stat-number" id="today-allocations">0</div>
                </div>
                
                <div class="fsc-stat-box">
                    <h3>低库存预警</h3>
                    <div class="stat-number warning" id="low-stock-alerts">0</div>
                </div>
            </div>
            
            <div class="fsc-charts-row">
                <div class="fsc-chart-container">
                    <h3>仓库负载率</h3>
                    <canvas id="warehouse-load-chart" width="400" height="200"></canvas>
                </div>
                
                <div class="fsc-chart-container">
                    <h3>库存分布</h3>
                    <canvas id="inventory-distribution-chart" width="400" height="200"></canvas>
                </div>
            </div>
            
            <div class="fsc-recent-activity">
                <h3>最近活动</h3>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th>时间</th>
                            <th>订单号</th>
                            <th>产品</th>
                            <th>仓库</th>
                            <th>数量</th>
                            <th>状态</th>
                        </tr>
                    </thead>
                    <tbody id="recent-activities">
                        <!-- 通过AJAX加载 -->
                    </tbody>
                </table>
            </div>
        </div>
        
        <style>
        .fsc-dashboard {
            padding: 20px;
        }
        
        .fsc-stats-row {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }
        
        .fsc-stat-box {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            text-align: center;
        }
        
        .fsc-stat-box h3 {
            margin: 0 0 10px 0;
            color: #666;
            font-size: 14px;
            text-transform: uppercase;
        }
        
        .stat-number {
            font-size: 32px;
            font-weight: bold;
            color: #2271b1;
        }
        
        .stat-number.warning {
            color: #d63638;
        }
        
        .fsc-charts-row {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
            gap: 20px;
            margin: 30px 0;
        }
        
        .fsc-chart-container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .fsc-recent-activity {
            margin-top: 30px;
        }
        </style>
        
        <script>
        jQuery(document).ready(function($) {
            // 加载仪表板数据
            function loadDashboardData() {
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'fsc_get_dashboard_data'
                    },
                    success: function(response) {
                        if (response.success) {
                            var data = response.data;
                            
                            // 更新统计数据
                            $('#active-warehouses').text(data.stats.active_warehouses);
                            $('#total-inventory').text(data.stats.total_inventory);
                            $('#today-allocations').text(data.stats.today_allocations);
                            $('#low-stock-alerts').text(data.stats.low_stock_alerts);
                            
                            // 更新最近活动
                            var activitiesHtml = '';
                            data.recent_activities.forEach(function(activity) {
                                activitiesHtml += '<tr>' +
                                    '<td>' + activity.time + '</td>' +
                                    '<td>#' + activity.order_id + '</td>' +
                                    '<td>' + activity.product_name + '</td>' +
                                    '<td>' + activity.warehouse_name + '</td>' +
                                    '<td>' + activity.quantity + '</td>' +
                                    '<td><span class="status-' + activity.status + '">' + activity.status_text + '</span></td>' +
                                '</tr>';
                            });
                            $('#recent-activities').html(activitiesHtml);
                            
                            // 渲染图表
                            renderCharts(data.charts);
                        }
                    }
                });
            }
            
            // 渲染图表
            function renderCharts(chartData) {
                // 仓库负载图表
                var loadCtx = document.getElementById('warehouse-load-chart').getContext('2d');
                new Chart(loadCtx, {
                    type: 'bar',
                    data: {
                        labels: chartData.warehouse_load.labels,
                        datasets: [{
                            label: '负载率 (%)',
                            data: chartData.warehouse_load.data,
                            backgroundColor: 'rgba(54, 162, 235, 0.5)',
                            borderColor: 'rgba(54, 162, 235, 1)',
                            borderWidth: 1
                        }]
                    },
                    options: {
                        responsive: true,
                        scales: {
                            y: {
                                beginAtZero: true,
                                max: 100
                            }
                        }
                    }
                });
                
                // 库存分布图表
                var distCtx = document.getElementById('inventory-distribution-chart').getContext('2d');
                new Chart(distCtx, {
                    type: 'doughnut',
                    data: {
                        labels: chartData.inventory_distribution.labels,
                        datasets: [{
                            data: chartData.inventory_distribution.data,
                            backgroundColor: [
                                '#FF6384',
                                '#36A2EB',
                                '#FFCE56',
                                '#4BC0C0',
                                '#9966FF',
                                '#FF9F40'
                            ]
                        }]
                    }
                });
            }
            
            // 初始加载
            loadDashboardData();
            
            // 每5分钟刷新一次
            setInterval(loadDashboardData, 300000);
        });
        </script>
        <?php
    }
    
    /**
     * AJAX获取仪表板数据
     */
    public function ajax_get_dashboard_data() {
        global $wpdb;
        
        // 验证权限
        if (!current_user_can('manage_options')) {
            wp_die('权限不足');
        }
        
        $data = array(
            'stats' => $this->get_dashboard_stats(),
            'recent_activities' => $this->get_recent_activities(),
            'charts' => $this->get_chart_data()
        );
        
        wp_send_json_success($data);
    }
    
    /**
     * 获取仪表板统计数据
     */
    private function get_dashboard_stats() {
        global $wpdb;
        
        $warehouses_table = $wpdb->prefix . 'fsc_warehouses';
        $inventory_table = $wpdb->prefix . 'fsc_inventory';
        $allocations_table = $wpdb->prefix . 'fsc_allocations';
        
        $stats = array(
            'active_warehouses' => $wpdb->get_var("SELECT COUNT(*) FROM $warehouses_table WHERE is_active = 1"),
            'total_inventory' => $wpdb->get_var("SELECT SUM(quantity) FROM $inventory_table"),
            'today_allocations' => $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $allocations_table WHERE DATE(created_at) = %s",
                date('Y-m-d')
            )),
            'low_stock_alerts' => $wpdb->get_var("SELECT COUNT(*) FROM $inventory_table WHERE status = 'low_stock'")
        );
        
        return $stats;
    }
}
?>

实时库存同步与API接口

创建REST API接口,实现与外部系统的集成:

<?php
/**
 * REST API接口
 */
class FSC_REST_API {
    
    public function __construct() {
        add_action('rest_api_init', array($this, 'register_routes'));
    }
    
    /**
     * 注册REST API路由
     */
    public function register_routes() {
        // 库存查询接口
        register_rest_route('fsc/v1', '/inventory/(?P<product_id>d+)', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_inventory'),
            'permission_callback' => array($this, 'check_api_permission'),
            'args' => array(
                'product_id' => array(
                    'validate_callback' => function($param) {
                        return is_numeric($param);
                    }
                )
            )
        ));
        
        // 库存更新接口
        register_rest_route('fsc/v1', '/inventory', array(
            'methods' => 'POST',
            'callback' => array($this, 'update_inventory'),
            'permission_callback' => array($this, 'check_api_permission')
        ));
        
        // 订单分配接口
        register_rest_route('fsc/v1', '/allocate', array(
            'methods' => 'POST',
            'callback' => array($this, 'allocate_order'),
            'permission_callback' => array($this, 'check_api_permission')
        ));
        
        // 仓库状态接口
        register_rest_route('fsc/v1', '/warehouses', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_warehouses'),
            'permission_callback' => array($this, 'check_api_permission')
        ));
    }
    
    /**
     * API权限检查
     */
    public function check_api_permission($request) {
        // 检查API密钥
        $api_key = $request->get_header('X-FSC-API-Key');
        
        if (!$api_key) {
            return new WP_Error('rest_forbidden', '缺少API密钥', array('status' => 401));
        }
        
        // 验证API密钥(这里应该从数据库或设置中获取)
        $valid_key = get_option('fsc_api_key', '');
        
        if ($api_key !== $valid_key) {
            return new WP_Error('rest_forbidden', '无效的API密钥', array('status' => 403));
        }
        
        return true;
    }
    
    /**
     * 获取库存信息
     */
    public function get_inventory($request) {
        global $wpdb;
        
        $product_id = $request['product_id'];
        $inventory_table = $wpdb->prefix . 'fsc_inventory';
        $warehouses_table = $wpdb->prefix . 'fsc_warehouses';
        
        $results = $wpdb->get_results($wpdb->prepare(
            "SELECT i.*, w.name as warehouse_name, w.location, 
                    (i.quantity - i.reserved_quantity) as available_quantity
             FROM $inventory_table i
             JOIN $warehouses_table w ON i.warehouse_id = w.id
             WHERE i.product_id = %d AND w.is_active = 1",
            $product_id
        ));
        
        $inventory_data = array();
        $total_available = 0;
        
        foreach ($results as $row) {
            $inventory_data[] = array(
                'warehouse_id' => $row->warehouse_id,
                'warehouse_name' => $row->warehouse_name,
                'location' => $row->location,
                'quantity' => $row->quantity,
                'reserved_quantity' => $row->reserved_quantity,
                'available_quantity' => $row->available_quantity,
                'safety_stock' => $row->safety_stock,
                'status' => $row->status,
                'last_updated' => $row->last_updated
            );
            
            $total_available += $row->available_quantity;
        }
        
        return array(
            'product_id' => $product_id,
            'total_available' => $total_available,
            'inventory' => $inventory_data,
            'timestamp' => current_time('mysql')
        );
    }
    
    /**
     * 更新库存
     */
    public function update_inventory($request) {
        global $wpdb;
        
        $params = $request->get_json_params();
        
        // 验证必要参数
        if (empty($params['warehouse_id']) || empty($params['product_id']) || !isset($params['quantity'])) {
            return new WP_Error('invalid_params', '缺少必要参数', array('status' => 400));
        }
        
        $inventory_table = $wpdb->prefix . 'fsc_inventory';
        
        // 检查记录是否存在
        $existing = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $inventory_table 
             WHERE warehouse_id = %d AND product_id = %d",
            $params['warehouse_id'], $params['product_id']
        ));
        
        if ($existing) {
            // 更新现有记录
            $wpdb->update(
                $inventory_table,
                array(
                    'quantity' => $params['quantity'],
                    'last_updated' => current_time('mysql')
                ),
                array(
                    'warehouse_id' => $params['warehouse_id'],
                    'product_id' => $params['product_id']
                )
            );
        } else {
            // 插入新记录
            $wpdb->insert(
                $inventory_table,
                array(
                    'warehouse_id' => $params['warehouse_id'],
                    'product_id' => $params['product_id'],
                    'quantity' => $params['quantity'],
                    'sku' => $params['sku'] ?? '',
                    'safety_stock' => $params['safety_stock'] ?? 10,
                    'reorder_point' => $params['reorder_point'] ?? 20
                )
            );
        }
        
        // 更新库存状态
        $this->update_inventory_status($params['warehouse_id'], $params['product_id']);
        
        return array(
            'success' => true,
            'message' => '库存更新成功',
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5689.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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