文章目录[隐藏]
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' => '库存更新成功',
