首页 / 教程文章 / WordPress柔性采购与库存预警系统开发教程

WordPress柔性采购与库存预警系统开发教程

WordPress柔性采购与库存预警系统开发教程

系统概述与设计思路

在当今电子商务快速发展的时代,库存管理成为企业运营的关键环节。WordPress作为全球最流行的内容管理系统,结合其强大的插件生态和自定义开发能力,可以构建出灵活高效的采购与库存预警系统。

本系统将实现以下核心功能:

  1. 实时库存监控与预警
  2. 智能采购建议生成
  3. 供应商管理集成
  4. 采购订单自动化处理
  5. 多仓库库存同步

系统采用模块化设计,便于后期功能扩展和维护。我们将使用WordPress自定义文章类型(CPT)存储产品信息,自定义数据库表记录库存变动,并结合REST API实现前后端数据交互。

环境准备与数据库设计

首先,我们需要在WordPress环境中创建必要的数据库表结构。在您的插件主文件中添加以下代码:

<?php
/**
 * WordPress柔性采购与库存预警系统
 * 数据库初始化模块
 */

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

class InventoryDB {
    
    /**
     * 创建库存相关数据表
     */
    public static function create_tables() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        
        // 库存变动记录表
        $table_inventory_log = $wpdb->prefix . 'inventory_log';
        $sql_inventory_log = "CREATE TABLE IF NOT EXISTS $table_inventory_log (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            product_id bigint(20) NOT NULL,
            warehouse_id int(11) DEFAULT 1,
            change_type varchar(50) NOT NULL COMMENT '变动类型: purchase, sale, adjust, return',
            change_qty int(11) NOT NULL COMMENT '变动数量,正数为入库,负数为出库',
            previous_qty int(11) NOT NULL COMMENT '变动前数量',
            current_qty int(11) NOT NULL COMMENT '变动后数量',
            reference_id bigint(20) DEFAULT NULL COMMENT '关联订单ID或采购单ID',
            operator_id bigint(20) DEFAULT NULL COMMENT '操作员ID',
            notes text COMMENT '备注信息',
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY idx_product (product_id),
            KEY idx_created (created_at)
        ) $charset_collate;";
        
        // 采购建议表
        $table_purchase_suggest = $wpdb->prefix . 'purchase_suggestions';
        $sql_purchase_suggest = "CREATE TABLE IF NOT EXISTS $table_purchase_suggest (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            product_id bigint(20) NOT NULL,
            suggested_qty int(11) NOT NULL COMMENT '建议采购数量',
            reason_code varchar(100) NOT NULL COMMENT '建议原因: low_stock, seasonal, trend',
            urgency_level tinyint(1) DEFAULT 1 COMMENT '紧急程度 1-5',
            calculated_at datetime DEFAULT CURRENT_TIMESTAMP,
            processed tinyint(1) DEFAULT 0 COMMENT '是否已处理',
            processed_at datetime DEFAULT NULL,
            PRIMARY KEY (id),
            KEY idx_product (product_id),
            KEY idx_urgency (urgency_level)
        ) $charset_collate;";
        
        // 供应商信息表
        $table_suppliers = $wpdb->prefix . 'suppliers';
        $sql_suppliers = "CREATE TABLE IF NOT EXISTS $table_suppliers (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            name varchar(200) NOT NULL,
            contact_person varchar(100) DEFAULT NULL,
            phone varchar(50) DEFAULT NULL,
            email varchar(100) DEFAULT NULL,
            lead_time int(11) DEFAULT 7 COMMENT '交货周期(天)',
            reliability_score decimal(3,2) DEFAULT 5.00 COMMENT '可靠性评分',
            payment_terms text COMMENT '付款条件',
            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;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql_inventory_log);
        dbDelta($sql_purchase_suggest);
        dbDelta($sql_suppliers);
    }
    
    /**
     * 删除数据表(用于插件卸载)
     */
    public static function drop_tables() {
        global $wpdb;
        
        $tables = [
            $wpdb->prefix . 'inventory_log',
            $wpdb->prefix . 'purchase_suggestions',
            $wpdb->prefix . 'suppliers'
        ];
        
        foreach ($tables as $table) {
            $wpdb->query("DROP TABLE IF EXISTS $table");
        }
    }
}

// 插件激活时创建表
register_activation_hook(__FILE__, ['InventoryDB', 'create_tables']);
// 插件卸载时删除表(根据需求选择是否启用)
// register_uninstall_hook(__FILE__, ['InventoryDB', 'drop_tables']);
?>

产品与库存管理模块

接下来,我们创建产品自定义文章类型并添加库存管理字段:

<?php
/**
 * 产品与库存管理模块
 */

class ProductInventoryManager {
    
    public function __construct() {
        // 注册产品自定义文章类型
        add_action('init', [$this, 'register_product_post_type']);
        
        // 添加库存管理元框
        add_action('add_meta_boxes', [$this, 'add_inventory_meta_box']);
        
        // 保存库存数据
        add_action('save_post_product', [$this, 'save_inventory_data'], 10, 2);
        
        // 添加库存管理列
        add_filter('manage_product_posts_columns', [$this, 'add_inventory_columns']);
        add_action('manage_product_posts_custom_column', [$this, 'display_inventory_columns'], 10, 2);
    }
    
    /**
     * 注册产品自定义文章类型
     */
    public function register_product_post_type() {
        $labels = [
            'name'               => '产品',
            'singular_name'      => '产品',
            'menu_name'          => '产品管理',
            'add_new'            => '添加产品',
            'add_new_item'       => '添加新产品',
            'edit_item'          => '编辑产品',
            'new_item'           => '新产品',
            'view_item'          => '查看产品',
            'search_items'       => '搜索产品',
            'not_found'          => '未找到产品',
            'not_found_in_trash' => '回收站中无产品'
        ];
        
        $args = [
            'labels'              => $labels,
            'public'              => true,
            'has_archive'         => true,
            'publicly_queryable'  => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'query_var'           => true,
            'rewrite'             => ['slug' => 'product'],
            'capability_type'     => 'post',
            'hierarchical'        => false,
            'menu_position'       => 30,
            'menu_icon'           => 'dashicons-products',
            'supports'            => ['title', 'editor', 'thumbnail', 'excerpt'],
            'show_in_rest'        => true
        ];
        
        register_post_type('product', $args);
    }
    
    /**
     * 添加库存管理元框
     */
    public function add_inventory_meta_box() {
        add_meta_box(
            'inventory_management',
            '库存管理',
            [$this, 'render_inventory_meta_box'],
            'product',
            'side',
            'high'
        );
    }
    
    /**
     * 渲染库存管理元框
     */
    public function render_inventory_meta_box($post) {
        // 获取现有库存数据
        $current_stock = get_post_meta($post->ID, '_current_stock', true) ?: 0;
        $min_stock = get_post_meta($post->ID, '_min_stock', true) ?: 10;
        $max_stock = get_post_meta($post->ID, '_max_stock', true) ?: 100;
        $supplier_id = get_post_meta($post->ID, '_primary_supplier', true);
        
        // 添加安全验证
        wp_nonce_field('save_inventory_data', 'inventory_nonce');
        
        // 显示表单
        ?>
        <div class="inventory-fields">
            <p>
                <label for="current_stock">当前库存:</label>
                <input type="number" id="current_stock" name="current_stock" 
                       value="<?php echo esc_attr($current_stock); ?>" class="widefat">
            </p>
            <p>
                <label for="min_stock">最低库存预警:</label>
                <input type="number" id="min_stock" name="min_stock" 
                       value="<?php echo esc_attr($min_stock); ?>" class="widefat">
            </p>
            <p>
                <label for="max_stock">最大库存量:</label>
                <input type="number" id="max_stock" name="max_stock" 
                       value="<?php echo esc_attr($max_stock); ?>" class="widefat">
            </p>
            <p>
                <label for="primary_supplier">主要供应商:</label>
                <?php $this->render_supplier_dropdown($supplier_id); ?>
            </p>
            
            <?php 
            // 显示库存状态
            $this->display_stock_status($current_stock, $min_stock, $max_stock);
            ?>
        </div>
        <?php
    }
    
    /**
     * 渲染供应商下拉列表
     */
    private function render_supplier_dropdown($selected_id) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'suppliers';
        $suppliers = $wpdb->get_results("SELECT id, name FROM $table_name WHERE is_active = 1");
        
        echo '<select id="primary_supplier" name="primary_supplier" class="widefat">';
        echo '<option value="">选择供应商</option>';
        
        foreach ($suppliers as $supplier) {
            $selected = ($supplier->id == $selected_id) ? 'selected' : '';
            echo '<option value="' . esc_attr($supplier->id) . '" ' . $selected . '>';
            echo esc_html($supplier->name);
            echo '</option>';
        }
        
        echo '</select>';
    }
    
    /**
     * 显示库存状态
     */
    private function display_stock_status($current, $min, $max) {
        $percentage = ($current / $max) * 100;
        $status_class = 'good';
        $status_text = '库存充足';
        
        if ($current <= $min) {
            $status_class = 'low';
            $status_text = '库存不足';
        } elseif ($current >= $max * 0.9) {
            $status_class = 'high';
            $status_text = '库存过高';
        }
        
        echo '<div class="stock-status ' . $status_class . '">';
        echo '<strong>状态:</strong> ' . $status_text;
        echo '<div class="stock-bar"><div class="stock-level" style="width:' . $percentage . '%;"></div></div>';
        echo '</div>';
        
        // 添加简单样式
        echo '<style>
            .stock-status { padding: 8px; margin: 10px 0; border-radius: 4px; }
            .stock-status.low { background: #ffeaea; border-left: 4px solid #dc3232; }
            .stock-status.good { background: #e7f7e7; border-left: 4px solid #46b450; }
            .stock-status.high { background: #fff3e6; border-left: 4px solid #ffb900; }
            .stock-bar { height: 10px; background: #f0f0f0; border-radius: 5px; margin-top: 5px; }
            .stock-level { height: 100%; background: #0073aa; border-radius: 5px; }
        </style>';
    }
    
    /**
     * 保存库存数据
     */
    public function save_inventory_data($post_id, $post) {
        // 安全检查
        if (!isset($_POST['inventory_nonce']) || 
            !wp_verify_nonce($_POST['inventory_nonce'], 'save_inventory_data')) {
            return;
        }
        
        // 权限检查
        if (!current_user_can('edit_post', $post_id)) {
            return;
        }
        
        // 自动保存检查
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }
        
        // 保存库存数据
        $fields = ['current_stock', 'min_stock', 'max_stock', 'primary_supplier'];
        
        foreach ($fields as $field) {
            if (isset($_POST[$field])) {
                $value = sanitize_text_field($_POST[$field]);
                update_post_meta($post_id, '_' . $field, $value);
            }
        }
        
        // 记录库存变动
        $this->log_inventory_change($post_id, 'adjust', $_POST['current_stock']);
    }
    
    /**
     * 记录库存变动
     */
    private function log_inventory_change($product_id, $type, $new_qty) {
        global $wpdb;
        
        $old_qty = get_post_meta($product_id, '_current_stock', true) ?: 0;
        $change_qty = $new_qty - $old_qty;
        
        if ($change_qty == 0) {
            return; // 库存未变化,不记录
        }
        
        $table_name = $wpdb->prefix . 'inventory_log';
        
        $wpdb->insert(
            $table_name,
            [
                'product_id' => $product_id,
                'change_type' => $type,
                'change_qty' => $change_qty,
                'previous_qty' => $old_qty,
                'current_qty' => $new_qty,
                'operator_id' => get_current_user_id(),
                'created_at' => current_time('mysql')
            ],
            ['%d', '%s', '%d', '%d', '%d', '%d', '%s']
        );
    }
    
    /**
     * 添加库存管理列
     */
    public function add_inventory_columns($columns) {
        $new_columns = [];
        
        foreach ($columns as $key => $value) {
            $new_columns[$key] = $value;
            
            if ($key === 'title') {
                $new_columns['current_stock'] = '当前库存';
                $new_columns['stock_status'] = '库存状态';
                $new_columns['last_updated'] = '最后更新';
            }
        }
        
        return $new_columns;
    }
    
    /**
     * 显示库存管理列内容
     */
    public function display_inventory_columns($column, $post_id) {
        switch ($column) {
            case 'current_stock':
                $stock = get_post_meta($post_id, '_current_stock', true);
                echo $stock ?: 0;
                break;
                
            case 'stock_status':
                $current = get_post_meta($post_id, '_current_stock', true) ?: 0;
                $min = get_post_meta($post_id, '_min_stock', true) ?: 10;
                
                if ($current <= $min) {
                    echo '<span style="color: #dc3232; font-weight: bold;">需补货</span>';
                } elseif ($current <= $min * 2) {
                    echo '<span style="color: #ffb900;">库存偏低</span>';
                } else {
                    echo '<span style="color: #46b450;">正常</span>';
                }
                break;
                
            case 'last_updated':
                global $wpdb;
                $table_name = $wpdb->prefix . 'inventory_log';
                $last_update = $wpdb->get_var($wpdb->prepare(
                    "SELECT created_at FROM $table_name 
                     WHERE product_id = %d 
                     ORDER BY created_at DESC LIMIT 1",
                    $post_id
                ));
                
                echo $last_update ? date('Y-m-d H:i', strtotime($last_update)) : '无记录';
                break;
        }
    }
}

// 初始化产品库存管理器
new ProductInventoryManager();
?>

智能预警与采购建议模块

库存预警是系统的核心功能,下面我们实现智能预警算法:

<?php
/**
 * 智能预警与采购建议模块
 */

class InventoryAlertSystem {
    
    private $alert_thresholds = [
        'critical' => 0.2,   // 低于最低库存20%为紧急
        'warning' => 0.5,    // 低于最低库存50%为警告
        'normal' => 1.0      // 低于最低库存100%为正常
    ];
    
    public function __construct() {
        // 每天检查库存
        add_action('wp', [$this, 'schedule_daily_check']);
        add_action('inventory_daily_check', [$this, 'check_all_products']);
        
        // 添加管理页面
        add_action('admin_menu', [$this, 'add_admin_pages']);
    }
    
    /**
     * 安排每日检查任务
     */
    public function schedule_daily_check() {
        if (!wp_next_scheduled('inventory_daily_check')) {
            wp_schedule_event(time(), 'daily', 'inventory_daily_check');
        }
    }
    
    /**
     * 检查所有产品库存
     */
    public function check_all_products() {
        $args = [
            'post_type' => 'product',
            'posts_per_page' => -1,
            'post_status' => 'publish'
        ];
        
        $products = get_posts($args);
        
        foreach ($products as $product) {
            $this->check_single_product($product->ID);
        }
        

智能预警与采购建议模块(续)

<?php
/**
 * 智能预警与采购建议模块(续)
 */

class InventoryAlertSystem {
    
    // ... 前面的构造函数和基础方法保持不变 ...
    
    /**
     * 检查单个产品库存状态
     */
    private function check_single_product($product_id) {
        $current_stock = (int) get_post_meta($product_id, '_current_stock', true);
        $min_stock = (int) get_post_meta($product_id, '_min_stock', true);
        $max_stock = (int) get_post_meta($product_id, '_max_stock', true);
        
        // 计算库存比率
        $stock_ratio = $min_stock > 0 ? $current_stock / $min_stock : 1;
        
        // 判断库存状态
        if ($current_stock <= 0) {
            $this->generate_purchase_suggestion($product_id, 'out_of_stock', 5);
            $this->send_alert_notification($product_id, 'critical', '产品已售罄');
        } elseif ($stock_ratio <= $this->alert_thresholds['critical']) {
            $suggest_qty = $max_stock - $current_stock;
            $this->generate_purchase_suggestion($product_id, 'critical_low', $suggest_qty, 5);
            $this->send_alert_notification($product_id, 'critical', '库存严重不足');
        } elseif ($stock_ratio <= $this->alert_thresholds['warning']) {
            $suggest_qty = ceil(($max_stock - $current_stock) * 0.7);
            $this->generate_purchase_suggestion($product_id, 'low_stock', $suggest_qty, 3);
            $this->send_alert_notification($product_id, 'warning', '库存偏低');
        }
        
        // 检查是否需要生成基于销售趋势的建议
        $this->check_sales_trend($product_id);
    }
    
    /**
     * 生成采购建议
     */
    private function generate_purchase_suggestion($product_id, $reason, $quantity, $urgency = 1) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'purchase_suggestions';
        
        // 检查是否已有未处理的相同建议
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $table_name 
             WHERE product_id = %d 
             AND reason_code = %s 
             AND processed = 0",
            $product_id, $reason
        ));
        
        if ($existing > 0) {
            return; // 已有相同建议,不再重复生成
        }
        
        $wpdb->insert(
            $table_name,
            [
                'product_id' => $product_id,
                'suggested_qty' => $quantity,
                'reason_code' => $reason,
                'urgency_level' => $urgency,
                'calculated_at' => current_time('mysql')
            ],
            ['%d', '%d', '%s', '%d', '%s']
        );
        
        // 记录到系统日志
        $this->log_system_event('purchase_suggestion_generated', [
            'product_id' => $product_id,
            'quantity' => $quantity,
            'reason' => $reason
        ]);
    }
    
    /**
     * 检查销售趋势
     */
    private function check_sales_trend($product_id) {
        global $wpdb;
        
        $log_table = $wpdb->prefix . 'inventory_log';
        
        // 获取最近30天的销售数据
        $thirty_days_ago = date('Y-m-d H:i:s', strtotime('-30 days'));
        
        $sales_data = $wpdb->get_results($wpdb->prepare(
            "SELECT DATE(created_at) as sale_date, 
                    SUM(ABS(change_qty)) as daily_sales
             FROM $log_table 
             WHERE product_id = %d 
             AND change_type = 'sale' 
             AND change_qty < 0 
             AND created_at >= %s
             GROUP BY DATE(created_at)
             ORDER BY sale_date DESC
             LIMIT 30",
            $product_id, $thirty_days_ago
        ));
        
        if (count($sales_data) < 7) {
            return; // 数据不足,不进行趋势分析
        }
        
        // 计算平均日销量
        $total_sales = 0;
        foreach ($sales_data as $data) {
            $total_sales += $data->daily_sales;
        }
        $avg_daily_sales = $total_sales / count($sales_data);
        
        // 获取当前库存和供应商交货周期
        $current_stock = (int) get_post_meta($product_id, '_current_stock', true);
        $supplier_id = get_post_meta($product_id, '_primary_supplier', true);
        $lead_time = $this->get_supplier_lead_time($supplier_id);
        
        // 计算安全库存(考虑交货周期和销售波动)
        $safety_stock = ceil($avg_daily_sales * $lead_time * 1.5);
        
        // 如果当前库存低于安全库存,生成采购建议
        if ($current_stock < $safety_stock) {
            $min_stock = (int) get_post_meta($product_id, '_min_stock', true);
            $suggest_qty = max($safety_stock - $current_stock, $min_stock - $current_stock);
            
            if ($suggest_qty > 0) {
                $this->generate_purchase_suggestion(
                    $product_id, 
                    'trend_based', 
                    $suggest_qty, 
                    2
                );
            }
        }
    }
    
    /**
     * 获取供应商交货周期
     */
    private function get_supplier_lead_time($supplier_id) {
        if (empty($supplier_id)) {
            return 7; // 默认7天
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'suppliers';
        
        $lead_time = $wpdb->get_var($wpdb->prepare(
            "SELECT lead_time FROM $table_name WHERE id = %d",
            $supplier_id
        ));
        
        return $lead_time ?: 7;
    }
    
    /**
     * 发送预警通知
     */
    private function send_alert_notification($product_id, $level, $message) {
        $product = get_post($product_id);
        $current_stock = get_post_meta($product_id, '_current_stock', true);
        $min_stock = get_post_meta($product_id, '_min_stock', true);
        
        // 获取管理员邮箱
        $admin_email = get_option('admin_email');
        
        $subject = sprintf('[库存预警] %s - %s', 
            ucfirst($level), 
            $product->post_title
        );
        
        $body = sprintf(
            "产品名称: %sn产品ID: %dn当前库存: %dn最低库存: %dn预警级别: %sn预警信息: %snn请登录系统查看详情: %s",
            $product->post_title,
            $product_id,
            $current_stock,
            $min_stock,
            $level,
            $message,
            admin_url('admin.php?page=inventory-alerts')
        );
        
        // 发送邮件
        wp_mail($admin_email, $subject, $body);
        
        // 记录通知发送
        $this->log_system_event('alert_notification_sent', [
            'product_id' => $product_id,
            'level' => $level,
            'message' => $message,
            'recipient' => $admin_email
        ]);
    }
    
    /**
     * 记录系统事件
     */
    private function log_system_event($event_type, $data = []) {
        global $wpdb;
        
        $log_table = $wpdb->prefix . 'inventory_log';
        
        $wpdb->insert(
            $log_table,
            [
                'product_id' => 0, // 0表示系统事件
                'change_type' => 'system_event',
                'change_qty' => 0,
                'previous_qty' => 0,
                'current_qty' => 0,
                'notes' => json_encode([
                    'event' => $event_type,
                    'data' => $data,
                    'timestamp' => current_time('mysql')
                ]),
                'created_at' => current_time('mysql')
            ],
            ['%d', '%s', '%d', '%d', '%d', '%s', '%s']
        );
    }
    
    /**
     * 添加管理页面
     */
    public function add_admin_pages() {
        add_menu_page(
            '库存预警系统',
            '库存预警',
            'manage_options',
            'inventory-alerts',
            [$this, 'render_alerts_page'],
            'dashicons-warning',
            56
        );
        
        add_submenu_page(
            'inventory-alerts',
            '采购建议',
            '采购建议',
            'manage_options',
            'purchase-suggestions',
            [$this, 'render_suggestions_page']
        );
    }
    
    /**
     * 渲染预警页面
     */
    public function render_alerts_page() {
        global $wpdb;
        
        $log_table = $wpdb->prefix . 'inventory_log';
        
        // 获取最近的预警记录
        $alerts = $wpdb->get_results(
            "SELECT l.*, p.post_title 
             FROM $log_table l
             LEFT JOIN {$wpdb->posts} p ON l.product_id = p.ID
             WHERE l.change_type = 'system_event'
             AND l.notes LIKE '%alert_notification_sent%'
             ORDER BY l.created_at DESC
             LIMIT 50"
        );
        
        ?>
        <div class="wrap">
            <h1>库存预警系统</h1>
            
            <div class="alert-summary">
                <h2>今日预警统计</h2>
                <?php $this->render_today_stats(); ?>
            </div>
            
            <div class="alert-list">
                <h2>最近预警记录</h2>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th>时间</th>
                            <th>产品</th>
                            <th>预警级别</th>
                            <th>详细信息</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($alerts as $alert): 
                            $notes = json_decode($alert->notes, true);
                        ?>
                        <tr>
                            <td><?php echo date('Y-m-d H:i', strtotime($alert->created_at)); ?></td>
                            <td>
                                <?php if ($alert->product_id > 0): ?>
                                    <a href="<?php echo get_edit_post_link($alert->product_id); ?>">
                                        <?php echo esc_html($alert->post_title ?: '产品#' . $alert->product_id); ?>
                                    </a>
                                <?php else: ?>
                                    系统事件
                                <?php endif; ?>
                            </td>
                            <td>
                                <?php 
                                $level = $notes['data']['level'] ?? 'unknown';
                                $level_labels = [
                                    'critical' => '<span class="dashicons dashicons-dismiss" style="color:#dc3232;"></span> 紧急',
                                    'warning' => '<span class="dashicons dashicons-warning" style="color:#ffb900;"></span> 警告',
                                    'normal' => '<span class="dashicons dashicons-yes" style="color:#46b450;"></span> 正常'
                                ];
                                echo $level_labels[$level] ?? $level;
                                ?>
                            </td>
                            <td><?php echo esc_html($notes['data']['message'] ?? ''); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        </div>
        
        <style>
            .alert-summary {
                background: #fff;
                padding: 20px;
                margin-bottom: 20px;
                border-radius: 4px;
                box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            }
            
            .stat-cards {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 20px;
                margin-top: 20px;
            }
            
            .stat-card {
                padding: 15px;
                border-radius: 4px;
                text-align: center;
            }
            
            .stat-card.critical {
                background: #ffeaea;
                border-left: 4px solid #dc3232;
            }
            
            .stat-card.warning {
                background: #fff3e6;
                border-left: 4px solid #ffb900;
            }
            
            .stat-card.normal {
                background: #e7f7e7;
                border-left: 4px solid #46b450;
            }
            
            .stat-number {
                font-size: 32px;
                font-weight: bold;
                display: block;
                margin-bottom: 5px;
            }
        </style>
        <?php
    }
    
    /**
     * 渲染今日统计
     */
    private function render_today_stats() {
        global $wpdb;
        
        $log_table = $wpdb->prefix . 'inventory_log';
        $today = date('Y-m-d');
        
        $stats = $wpdb->get_results(
            "SELECT 
                SUM(CASE WHEN notes LIKE '%critical%' THEN 1 ELSE 0 END) as critical_count,
                SUM(CASE WHEN notes LIKE '%warning%' THEN 1 ELSE 0 END) as warning_count,
                SUM(CASE WHEN notes LIKE '%normal%' THEN 1 ELSE 0 END) as normal_count
             FROM $log_table 
             WHERE DATE(created_at) = '$today'
             AND change_type = 'system_event'
             AND notes LIKE '%alert_notification_sent%'"
        );
        
        $stat = $stats[0] ?? (object) [
            'critical_count' => 0,
            'warning_count' => 0,
            'normal_count' => 0
        ];
        
        ?>
        <div class="stat-cards">
            <div class="stat-card critical">
                <span class="stat-number"><?php echo $stat->critical_count; ?></span>
                <span>紧急预警</span>
            </div>
            <div class="stat-card warning">
                <span class="stat-number"><?php echo $stat->warning_count; ?></span>
                <span>警告预警</span>
            </div>
            <div class="stat-card normal">
                <span class="stat-number"><?php echo $stat->normal_count; ?></span>
                <span>正常通知</span>
            </div>
        </div>
        <?php
    }
    
    /**
     * 渲染采购建议页面
     */
    public function render_suggestions_page() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'purchase_suggestions';
        
        // 处理建议操作
        if (isset($_POST['action']) && isset($_POST['suggestion_id'])) {
            $this->process_suggestion_action($_POST['suggestion_id'], $_POST['action']);
        }
        
        // 获取未处理的采购建议
        $suggestions = $wpdb->get_results(
            "SELECT s.*, p.post_title, 
                    pm1.meta_value as current_stock,
                    pm2.meta_value as min_stock,
                    pm3.meta_value as primary_supplier
             FROM $table_name s
             LEFT JOIN {$wpdb->posts} p ON s.product_id = p.ID
             LEFT JOIN {$wpdb->postmeta} pm1 ON s.product_id = pm1.post_id AND pm1.meta_key = '_current_stock'
             LEFT JOIN {$wpdb->postmeta} pm2 ON s.product_id = pm2.post_id AND pm2.meta_key = '_min_stock'
             LEFT JOIN {$wpdb->postmeta} pm3 ON s.product_id = pm3.post_id AND pm3.meta_key = '_primary_supplier'
             WHERE s.processed = 0
             ORDER BY s.urgency_level DESC, s.calculated_at DESC"
        );
        
        ?>
        <div class="wrap">
            <h1>采购建议</h1>
            
            <div class="notice notice-info">
                <p>系统根据库存情况和销售趋势自动生成的采购建议。请及时处理紧急建议。</p>
            </div>
            
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th>产品名称</th>
                        <th>当前库存</th>
                        <th>建议数量</th>
                        <th>建议原因</th>
                        <th>紧急程度</th>
                        <th>生成时间</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($suggestions as $suggestion): 
                        $reason_labels = [
                            'out_of_stock' => '已售罄',
                            'critical_low' => '库存严重不足',
                            'low_stock' => '库存偏低',
                            'trend_based' => '基于销售趋势'
                        ];
                    ?>
                    <tr>
                        <td>
                            <a href="<?php echo get_edit_post_link($suggestion->product_id); ?>">
                                <?php echo esc_html($suggestion->post_title ?: '产品#' . $suggestion->product_id); ?>
                            </a>
                        </td>
                        <td><?php echo $suggestion->current_stock ?: 0; ?></td>
                        <td><strong><?php echo $suggestion->suggested_qty; ?></strong></td>
                        <td><?php echo $reason_labels[$suggestion->reason_code] ?? $suggestion->reason_code; ?></td>
                        <td>
                            <?php 
                            $urgency_stars = str_repeat('★', $suggestion->urgency_level);
                            $urgency_class = $suggestion->urgency_level >= 4 ? 'critical' : 
                                           ($suggestion->urgency_level >= 3 ? 'warning' : 'normal');
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5745.html

EXCHANGES®作者

EXCHANGES® 技术支持:漳州柔性供应链服务有限公司
上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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