文章目录[隐藏]
WordPress柔性供应链软件实现动态安全库存设置的教程
引言:为什么需要动态安全库存?
在当今快速变化的电商环境中,静态的安全库存设置已经无法满足企业的需求。传统固定安全库存模式往往导致库存积压或缺货风险,影响企业现金流和客户满意度。柔性供应链系统通过动态调整安全库存水平,能够根据实际需求波动、供应链可靠性和市场变化自动优化库存水平,显著降低运营成本并提高服务水平。
本教程将详细介绍如何在WordPress环境中实现动态安全库存设置,通过完整的代码示例和分步指导,帮助您构建智能化的库存管理系统。
环境准备与插件选择
1. 系统要求
- WordPress 5.0或更高版本
- PHP 7.4或更高版本
- MySQL 5.6或更高版本
- WooCommerce插件(如果涉及电商功能)
2. 推荐插件
- Advanced Custom Fields:用于创建自定义库存设置字段
- WooCommerce:作为电商基础平台(可选)
- Query Monitor:调试和性能分析
3. 创建自定义插件
首先,我们需要创建一个自定义插件来处理动态安全库存逻辑:
<?php
/**
* Plugin Name: 柔性供应链动态安全库存系统
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站提供动态安全库存管理功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('FLEXIBLE_SCM_VERSION', '1.0.0');
define('FLEXIBLE_SCM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FLEXIBLE_SCM_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
add_action('plugins_loaded', 'flexible_scm_init');
function flexible_scm_init() {
// 检查必要组件
if (!class_exists('ACF')) {
add_action('admin_notices', 'flexible_scm_acf_notice');
return;
}
// 加载核心功能
require_once FLEXIBLE_SCM_PLUGIN_DIR . 'includes/class-dynamic-inventory.php';
require_once FLEXIBLE_SCM_PLUGIN_DIR . 'includes/class-safety-stock-calculator.php';
// 初始化主类
$dynamic_inventory = new Dynamic_Inventory();
$dynamic_inventory->init();
}
function flexible_scm_acf_notice() {
?>
<div class="notice notice-error">
<p>柔性供应链系统需要Advanced Custom Fields插件。请先安装并激活ACF插件。</p>
</div>
<?php
}
动态安全库存算法实现
1. 安全库存计算模型
动态安全库存的核心是基于统计学的需求预测模型。以下是基于服务水平法的安全库存计算实现:
<?php
/**
* 安全库存计算器类
* 实现动态安全库存算法
*/
class Safety_Stock_Calculator {
/**
* 计算动态安全库存
*
* @param float $avg_demand 平均日需求量
* @param float $demand_std 需求标准差
* @param float $lead_time 平均交货期(天)
* @param float $lead_time_std 交货期标准差
* @param float $service_level 服务水平(0-1之间,如0.95表示95%)
* @return float 计算出的安全库存量
*/
public function calculate_dynamic_safety_stock($avg_demand, $demand_std, $lead_time, $lead_time_std, $service_level) {
// 验证输入参数
if ($avg_demand <= 0 || $lead_time <= 0 || $service_level <= 0 || $service_level >= 1) {
throw new InvalidArgumentException('无效的输入参数');
}
// 计算Z值(基于服务水平的标准正态分布分位数)
$z_score = $this->calculate_z_score($service_level);
// 计算联合标准差(考虑需求和交货期的波动性)
$combined_variance = ($lead_time * pow($demand_std, 2)) + (pow($avg_demand, 2) * pow($lead_time_std, 2));
$combined_std = sqrt($combined_variance);
// 计算安全库存
$safety_stock = $z_score * $combined_std;
// 确保安全库存不为负数
return max(0, round($safety_stock, 2));
}
/**
* 计算Z分数(标准正态分布的分位数)
* 使用近似公式计算,避免依赖统计库
*
* @param float $probability 概率值(0-1)
* @return float Z分数
*/
private function calculate_z_score($probability) {
// 使用Hastings近似公式计算Z分数
if ($probability <= 0 || $probability >= 1) {
return 0;
}
// 对于常见的服务水平,使用预定义值提高性能
$common_z_scores = [
0.90 => 1.28,
0.95 => 1.65,
0.99 => 2.33
];
if (isset($common_z_scores[$probability])) {
return $common_z_scores[$probability];
}
// 使用近似公式计算
$t = sqrt(log(1 / pow($probability, 2)));
$c0 = 2.515517;
$c1 = 0.802853;
$c2 = 0.010328;
$d1 = 1.432788;
$d2 = 0.189269;
$d3 = 0.001308;
$z = $t - (($c0 + $c1 * $t + $c2 * pow($t, 2)) /
(1 + $d1 * $t + $d2 * pow($t, 2) + $d3 * pow($t, 3)));
return $probability > 0.5 ? $z : -$z;
}
/**
* 基于历史销售数据计算需求统计
*
* @param array $sales_data 历史销售数据数组
* @return array 包含平均需求和标准差的数组
*/
public function calculate_demand_statistics($sales_data) {
if (empty($sales_data) || count($sales_data) < 2) {
return ['avg' => 0, 'std' => 0];
}
$n = count($sales_data);
$sum = array_sum($sales_data);
$avg = $sum / $n;
// 计算标准差
$variance_sum = 0;
foreach ($sales_data as $value) {
$variance_sum += pow($value - $avg, 2);
}
$std = sqrt($variance_sum / ($n - 1));
return [
'avg' => round($avg, 2),
'std' => round($std, 2)
];
}
}
WordPress集成实现
1. 创建产品库存管理界面
/**
* 动态库存管理主类
*/
class Dynamic_Inventory {
public function init() {
// 添加管理菜单
add_action('admin_menu', [$this, 'add_admin_menu']);
// 添加产品自定义字段
add_action('acf/init', [$this, 'add_product_inventory_fields']);
// 覆盖WooCommerce库存管理(如果启用)
if (class_exists('WooCommerce')) {
add_filter('woocommerce_product_get_stock_quantity', [$this, 'adjust_stock_quantity'], 10, 2);
add_action('woocommerce_product_options_inventory_product_data', [$this, 'add_inventory_settings']);
}
// 定期重新计算安全库存
add_action('flexible_scm_daily_cron', [$this, 'recalculate_safety_stocks']);
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'动态库存管理',
'动态库存',
'manage_options',
'dynamic-inventory',
[$this, 'render_admin_page'],
'dashicons-chart-line',
56
);
}
/**
* 渲染管理页面
*/
public function render_admin_page() {
?>
<div class="wrap">
<h1>动态安全库存管理系统</h1>
<div class="card">
<h2>系统概览</h2>
<p>当前系统状态:<span class="status-active">运行中</span></p>
<div class="stats-container">
<div class="stat-box">
<h3>已监控产品</h3>
<p class="stat-number"><?php echo $this->get_monitored_product_count(); ?></p>
</div>
<div class="stat-box">
<h3>平均安全库存水平</h3>
<p class="stat-number"><?php echo $this->get_avg_safety_stock(); ?> 单位</p>
</div>
<div class="stat-box">
<h3>缺货风险降低</h3>
<p class="stat-number"><?php echo $this->get_stockout_reduction(); ?>%</p>
</div>
</div>
</div>
<div class="card">
<h2>批量重新计算</h2>
<button id="recalculate-all" class="button button-primary">重新计算所有产品安全库存</button>
<div id="recalculation-progress" style="display:none; margin-top:10px;">
<p>处理中... <span id="progress-percentage">0%</span></p>
<div class="progress-bar">
<div class="progress-fill" style="width:0%"></div>
</div>
</div>
</div>
</div>
<style>
.stat-box {
display: inline-block;
width: 30%;
padding: 15px;
margin: 10px;
background: #f5f5f5;
border-radius: 5px;
text-align: center;
}
.stat-number {
font-size: 24px;
font-weight: bold;
color: #0073aa;
}
.progress-bar {
width: 100%;
height: 20px;
background: #ddd;
border-radius: 10px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #0073aa;
transition: width 0.3s;
}
</style>
<script>
jQuery(document).ready(function($) {
$('#recalculate-all').click(function() {
$('#recalculation-progress').show();
recalculateBatch(0);
});
function recalculateBatch(offset) {
$.post(ajaxurl, {
action: 'recalculate_safety_stock_batch',
offset: offset,
nonce: '<?php echo wp_create_nonce("recalculate_batch"); ?>'
}, function(response) {
if (response.success) {
var percentage = Math.round((response.data.processed / response.data.total) * 100);
$('#progress-percentage').text(percentage + '%');
$('.progress-fill').css('width', percentage + '%');
if (response.data.completed) {
alert('重新计算完成!');
$('#recalculation-progress').hide();
} else {
recalculateBatch(response.data.next_offset);
}
}
});
}
});
</script>
<?php
}
/**
* 添加产品库存自定义字段
*/
public function add_product_inventory_fields() {
if (function_exists('acf_add_local_field_group')) {
acf_add_local_field_group([
'key' => 'group_dynamic_inventory',
'title' => '动态库存设置',
'fields' => [
[
'key' => 'field_enable_dynamic_stock',
'label' => '启用动态安全库存',
'name' => 'enable_dynamic_stock',
'type' => 'true_false',
'instructions' => '启用后系统将自动计算和调整安全库存',
'default_value' => 1
],
[
'key' => 'field_target_service_level',
'label' => '目标服务水平',
'name' => 'target_service_level',
'type' => 'number',
'instructions' => '期望的服务水平(0-1之间,如0.95表示95%)',
'min' => 0.5,
'max' => 0.99,
'step' => 0.01,
'default_value' => 0.95
],
[
'key' => 'field_lead_time_days',
'label' => '平均交货期(天)',
'name' => 'lead_time_days',
'type' => 'number',
'instructions' => '从下单到收货的平均时间',
'min' => 1,
'default_value' => 7
],
[
'key' => 'field_lead_time_std',
'label' => '交货期标准差',
'name' => 'lead_time_std',
'type' => 'number',
'instructions' => '交货期的波动程度',
'min' => 0,
'default_value' => 2
]
],
'location' => [
[
[
'param' => 'post_type',
'operator' => '==',
'value' => 'product',
],
],
],
]);
}
}
}
数据收集与自动化处理
1. 销售数据收集器
/**
* 销售数据收集与分析类
*/
class Sales_Data_Collector {
private $calculator;
public function __construct() {
$this->calculator = new Safety_Stock_Calculator();
}
/**
* 收集产品历史销售数据
*
* @param int $product_id 产品ID
* @param int $days 回溯天数
* @return array 销售数据数组
*/
public function collect_sales_data($product_id, $days = 90) {
global $wpdb;
$start_date = date('Y-m-d', strtotime("-{$days} days"));
// 查询销售数据
$query = $wpdb->prepare("
SELECT
DATE(post_date) as sale_date,
SUM(meta_value) as daily_quantity
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
WHERE p.post_type = 'shop_order'
AND p.post_status IN ('wc-completed', 'wc-processing')
AND oi.order_item_type = 'line_item'
AND oim.meta_key = '_product_id'
AND oim.meta_value = %d
AND p.post_date >= %s
GROUP BY DATE(p.post_date)
ORDER BY sale_date ASC
", $product_id, $start_date);
$results = $wpdb->get_results($query);
$sales_data = [];
foreach ($results as $row) {
$sales_data[] = (float) $row->daily_quantity;
}
return $sales_data;
}
/**
* 更新产品安全库存
*
* @param int $product_id 产品ID
* @return bool 是否成功更新
*/
public function update_product_safety_stock($product_id) {
// 检查是否启用动态库存
$enable_dynamic = get_field('enable_dynamic_stock', $product_id);
if (!$enable_dynamic) {
return false;
}
// 收集销售数据
$sales_data = $this->collect_sales_data($product_id);
if (count($sales_data) < 7) {
// 数据不足,使用默认值
return false;
}
// 计算需求统计
$demand_stats = $this->calculator->calculate_demand_statistics($sales_data);
// 获取产品设置
$service_level = get_field('target_service_level', $product_id) ?: 0.95;
$lead_time = get_field('lead_time_days', $product_id) ?: 7;
$lead_time_std = get_field('lead_time_std', $product_id) ?: 2;
// 计算安全库存
$safety_stock = $this->calculator->calculate_dynamic_safety_stock(
$demand_stats['avg'],
$demand_stats['std'],
$lead_time,
$lead_time_std,
$service_level
);
// 保存安全库存值
update_post_meta($product_id, '_dynamic_safety_stock', $safety_stock);
update_post_meta($product_id, '_last_safety_stock_calculation', current_time('mysql'));
// 更新WooCommerce库存阈值(如果适用)
if (class_exists('WooCommerce')) {
$product = wc_get_product($product_id);
if ($product && $product->managing_stock()) {
// 设置低库存阈值
$product->set_low_stock_amount($safety_stock);
$product->save();
}
}
return true;
}
}
部署与优化建议
1. 性能优化策略
/**
* 性能优化与缓存管理
*/
class Inventory_Performance_Optimizer {
/**
* 实现缓存机制,减少数据库查询
*/
public static function get_cached_safety_stock($product_id) {
$cache_key = 'safety_stock_' . $product_id;
$cached_value = wp_cache_get($cache_key, 'dynamic_inventory');
if (false !== $cached_value) {
return $cached_value;
}
// 从数据库获取
$safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
if ('' === $safety_stock) {
// 如果不存在,计算并保存
$collector = new Sales_Data_Collector();
$collector->update_product_safety_stock($product_id);
$safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
}
// 缓存12小时
wp_cache_set($cache_key, $safety_stock, 'dynamic_inventory', 12 * HOUR_IN_SECONDS);
return $safety_stock;
}
/**
* 批量处理优化
*/
public static function batch_update_safety_stocks($product_ids, $batch_size = 50) {
$results = [
'success' => 0,
'failed' => 0,
'skipped' => 0
];
$collector = new Sales_Data_Collector();
foreach (array_chunk($product_ids, $batch_size) as $chunk) {
foreach ($chunk as $product_id) {
// 检查是否启用动态库存
if (!get_field('enable_dynamic_stock', $product_id)) {
$results['skipped']++;
continue;
}
try {
if ($collector->update_product_safety_stock($product_id)) {
$results['success']++;
} else {
$results['failed']++;
}
} catch (Exception $e) {
error_log('安全库存更新失败 - 产品ID: ' . $product_id . ' - 错误: ' . $e->getMessage());
$results['failed']++;
}
}
// 每批处理后暂停,减少服务器负载
usleep(100000); // 0.1秒
}
return $results;
}
}
2. 自动化调度系统
/**
* 自动化任务调度器
*/
class Inventory_Scheduler {
public function init() {
// 注册定时任务
add_filter('cron_schedules', [$this, 'add_custom_schedules']);
add_action('init', [$this, 'schedule_events']);
}
/**
* 添加自定义调度间隔
*/
public function add_custom_schedules($schedules) {
$schedules['six_hours'] = [
'interval' => 6 * HOUR_IN_SECONDS,
'display' => __('每6小时')
];
$schedules['weekly'] = [
'interval' => 7 * DAY_IN_SECONDS,
'display' => __('每周')
];
return $schedules;
}
/**
* 安排定时事件
*/
public function schedule_events() {
if (!wp_next_scheduled('flexible_scm_daily_calculation')) {
wp_schedule_event(time(), 'daily', 'flexible_scm_daily_calculation');
}
if (!wp_next_scheduled('flexible_scm_weekly_report')) {
wp_schedule_event(time(), 'weekly', 'flexible_scm_weekly_report');
}
// 绑定事件处理函数
add_action('flexible_scm_daily_calculation', [$this, 'run_daily_calculations']);
add_action('flexible_scm_weekly_report', [$this, 'generate_weekly_report']);
}
/**
* 执行每日计算任务
*/
public function run_daily_calculations() {
global $wpdb;
// 获取所有启用动态库存的产品
$query = "
SELECT p.ID
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm.meta_key = 'enable_dynamic_stock'
AND pm.meta_value = '1'
LIMIT 200
";
$product_ids = $wpdb->get_col($query);
if (!empty($product_ids)) {
$optimizer = new Inventory_Performance_Optimizer();
$results = $optimizer->batch_update_safety_stocks($product_ids);
// 记录执行日志
$this->log_calculation_results($results);
}
}
/**
* 生成周度报告
*/
public function generate_weekly_report() {
global $wpdb;
$report_data = [
'period' => date('Y-m-d', strtotime('-7 days')) . ' 至 ' . date('Y-m-d'),
'total_products' => 0,
'active_products' => 0,
'avg_safety_stock' => 0,
'stockout_events' => 0,
'inventory_turnover' => 0
];
// 获取统计数据
$query = "
SELECT
COUNT(DISTINCT p.ID) as total_products,
COUNT(DISTINCT CASE WHEN pm.meta_value = '1' THEN p.ID END) as active_products,
AVG(CAST(pm2.meta_value AS DECIMAL(10,2))) as avg_safety_stock
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'enable_dynamic_stock'
LEFT JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_dynamic_safety_stock'
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
";
$stats = $wpdb->get_row($query);
if ($stats) {
$report_data['total_products'] = $stats->total_products;
$report_data['active_products'] = $stats->active_products;
$report_data['avg_safety_stock'] = round($stats->avg_safety_stock, 2);
}
// 发送报告邮件
$this->send_report_email($report_data);
}
/**
* 记录计算日志
*/
private function log_calculation_results($results) {
$log_entry = sprintf(
"[%s] 安全库存计算完成 - 成功: %d, 失败: %d, 跳过: %d",
current_time('mysql'),
$results['success'],
$results['failed'],
$results['skipped']
);
error_log($log_entry);
}
/**
* 发送报告邮件
*/
private function send_report_email($report_data) {
$to = get_option('admin_email');
$subject = '柔性供应链系统周度报告 - ' . date('Y-m-d');
$message = "
<h2>柔性供应链系统周度报告</h2>
<p>报告周期: {$report_data['period']}</p>
<table border='1' cellpadding='10' style='border-collapse: collapse;'>
<tr>
<th>指标</th>
<th>数值</th>
</tr>
<tr>
<td>总产品数</td>
<td>{$report_data['total_products']}</td>
</tr>
<tr>
<td>启用动态库存产品数</td>
<td>{$report_data['active_products']}</td>
</tr>
<tr>
<td>平均安全库存水平</td>
<td>{$report_data['avg_safety_stock']}</td>
</tr>
</table>
<p>报告生成时间: " . current_time('mysql') . "</p>
";
$headers = ['Content-Type: text/html; charset=UTF-8'];
wp_mail($to, $subject, $message, $headers);
}
}
前端展示与用户界面
1. 产品库存状态显示
/**
* 前端库存显示增强
*/
class Frontend_Inventory_Display {
public function init() {
// 在产品页面显示动态库存信息
add_action('woocommerce_single_product_summary', [$this, 'display_safety_stock_info'], 25);
// 在库存管理页面添加列
add_filter('manage_product_posts_columns', [$this, 'add_inventory_columns']);
add_action('manage_product_posts_custom_column', [$this, 'render_inventory_columns'], 10, 2);
// 添加库存预警短代码
add_shortcode('inventory_alert', [$this, 'inventory_alert_shortcode']);
}
/**
* 在产品页面显示安全库存信息
*/
public function display_safety_stock_info() {
global $product;
if (!$product || !$product->get_id()) {
return;
}
$product_id = $product->get_id();
$enable_dynamic = get_field('enable_dynamic_stock', $product_id);
if (!$enable_dynamic) {
return;
}
$safety_stock = Inventory_Performance_Optimizer::get_cached_safety_stock($product_id);
$current_stock = $product->get_stock_quantity();
if ($current_stock === null) {
return;
}
$stock_status = '';
$stock_class = '';
if ($current_stock <= $safety_stock) {
$stock_status = '库存预警';
$stock_class = 'stock-warning';
} elseif ($current_stock <= $safety_stock * 1.5) {
$stock_status = '库存适中';
$stock_class = 'stock-moderate';
} else {
$stock_status = '库存充足';
$stock_class = 'stock-good';
}
?>
<div class="dynamic-inventory-info">
<h3>库存状态</h3>
<div class="stock-status <?php echo esc_attr($stock_class); ?>">
<span class="status-label"><?php echo esc_html($stock_status); ?></span>
<div class="stock-details">
<p>当前库存: <strong><?php echo esc_html($current_stock); ?></strong> 单位</p>
<p>安全库存水平: <strong><?php echo esc_html($safety_stock); ?></strong> 单位</p>
<p>最后更新: <?php echo esc_html(get_post_meta($product_id, '_last_safety_stock_calculation', true)); ?></p>
</div>
</div>
</div>
<style>
.dynamic-inventory-info {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
background: #f9f9f9;
}
.stock-status {
padding: 10px;
border-radius: 4px;
margin: 10px 0;
}
.stock-warning {
background: #ffe6e6;
border-left: 4px solid #ff3333;
}
.stock-moderate {
background: #fff9e6;
border-left: 4px solid #ffcc00;
}
.stock-good {
background: #e6ffe6;
border-left: 4px solid #33cc33;
}
.status-label {
font-weight: bold;
font-size: 16px;
}
.stock-details {
margin-top: 10px;
font-size: 14px;
}
</style>
<?php
}
/**
* 添加库存管理列
*/
public function add_inventory_columns($columns) {
$new_columns = [];
foreach ($columns as $key => $value) {
$new_columns[$key] = $value;
if ($key === 'price') {
$new_columns['safety_stock'] = __('安全库存', 'flexible-scm');
$new_columns['stock_status'] = __('库存状态', 'flexible-scm');
}
}
return $new_columns;
}
/**
* 渲染库存管理列
*/
public function render_inventory_columns($column, $product_id) {
if ($column === 'safety_stock') {
$enable_dynamic = get_field('enable_dynamic_stock', $product_id);
if ($enable_dynamic) {
$safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
echo $safety_stock ? esc_html($safety_stock) : '<em>未计算</em>';
} else {
echo '<em>未启用</em>';
}
}
if ($column === 'stock_status') {
$product = wc_get_product($product_id);
$current_stock = $product->get_stock_quantity();
if ($current_stock !== null) {
$safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
if ($current_stock <= $safety_stock) {
echo '<span style="color: #ff3333; font-weight: bold;">⚠️ 预警</span>';
} elseif ($current_stock <= $safety_stock * 1.5) {
echo '<span style="color: #ffcc00;">⚠️ 注意</span>';
} else {
echo '<span style="color: #33cc33;">✓ 正常</span>';
}
}
}
}
/**
* 库存预警短代码
*/
public function inventory_alert_shortcode($atts) {
$atts = shortcode_atts([
'category' => '',
'limit' => 10,
'show_all' => false
], $atts);
$args = [
'post_type' => 'product',
'posts_per_page' => intval($atts['limit']),
'meta_query' => [
[
'key' => 'enable_dynamic_stock',
'value' => '1',
'compare' => '='
]
]
];
if (!empty($atts['category'])) {
$args['tax_query'] = [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category']
]
];
}
$products = new WP_Query($args);
if (!$products->have_posts()) {
return '<p>暂无库存预警产品</p>';
}
$output = '<div class="inventory-alert-list">';
$output .= '<h3>库存预警产品</h3>';
$output .= '<table class="inventory-alert-table">';
$output .= '<thead><tr><th>产品名称</th><th>当前库存</th><th>安全库存</th><th>状态</th></tr></thead>';
$output .= '<tbody>';
while ($products->have_posts()) {
$products->the_post();
$product_id = get_the_ID();
$product = wc_get_product($product_id);
$current_stock = $product->get_stock_quantity();
$safety_stock = get_post_meta($product_id, '_dynamic_safety_stock', true);
if ($atts['show_all'] || $current_stock <= $safety_stock) {
$status = $current_stock <= $safety_stock ? '预警' : '正常';
$status_class = $current_stock <= $safety_stock ? 'alert' : 'normal';
$output .= sprintf(
'<tr class="%s">
<td><a href="%s">%s</a></td>
<td>%s</td>
<td>%s</td>
<td><span class="status-%s">%s</span></td>
</tr>',
esc_attr($status_class),
get_permalink(),
get_the_title(),
esc_html($current_stock),
esc_html($safety_stock),
esc_attr($status_class),
esc_html($status)
);
}
}
wp_reset_postdata();
$output .= '</tbody></table></div>';
$output .= '
<style>
.inventory-alert-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
.inventory-alert-table th,
.inventory-alert-table td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.inventory-alert-table th {
background: #f5f5f5;
font-weight: bold;
}
.inventory-alert-table tr.alert {
background: #ffe6e6;
}
.inventory-alert-table tr.normal {
background: #e6ffe6;
}
.status-alert {
color: #ff3333;
font-weight: bold;
}
.status-normal {
color: #33cc33;
}
</style>';
return $output;
}
}
系统测试与验证
1. 单元测试类
/**
* 系统测试类
*/
class Flexible_SCM_Test {
/**
* 运行所有测试
*/
public static function run_all_tests() {
$results = [
'calculator' => self::test_calculator(),
'data_collection' => self::test_data_collection(),
'performance' => self::test_performance(),
'integration' => self::test_integration()
];
return $results;
}
/**
* 测试安全库存计算器
*/
