首页 / 教程文章 / WordPress文创商品柔性库存共享插件开发指南

WordPress文创商品柔性库存共享插件开发指南

WordPress文创商品柔性库存共享插件开发指南

引言:文创商品库存管理的挑战与机遇

在文创产业蓬勃发展的今天,许多文创品牌面临着库存管理的双重挑战:一方面需要避免库存积压造成的资金压力,另一方面又担心缺货错失销售机会。传统的库存管理模式往往僵化,无法适应文创商品销售波动大、季节性强的特点。

柔性库存共享机制为解决这一难题提供了创新思路。通过建立多店铺、多渠道间的库存共享网络,文创商家可以实现库存的动态调配,提高库存周转率,降低运营成本。本文将详细介绍如何开发一个WordPress文创商品柔性库存共享插件,帮助文创品牌实现智能化的库存管理。

插件架构设计

核心功能模块

我们的插件将包含以下核心模块:

  1. 库存共享网络管理
  2. 实时库存同步系统
  3. 智能库存分配算法
  4. 订单与库存联动机制
  5. 数据统计与分析面板

数据库设计

首先,我们需要设计插件的数据表结构:

/**
 * 创建插件所需的数据表
 * 这段代码应该放在插件的激活钩子中执行
 */
function wc_flexible_inventory_create_tables() {
    global $wpdb;
    
    $charset_collate = $wpdb->get_charset_collate();
    
    // 库存共享网络表
    $network_table = $wpdb->prefix . 'wc_flex_inventory_network';
    $network_sql = "CREATE TABLE IF NOT EXISTS $network_table (
        network_id bigint(20) NOT NULL AUTO_INCREMENT,
        store_name varchar(200) NOT NULL,
        store_url varchar(500) NOT NULL,
        api_key varchar(100) NOT NULL,
        status enum('active','inactive','pending') DEFAULT 'pending',
        inventory_share_percentage int(3) DEFAULT 100,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (network_id),
        UNIQUE KEY store_url (store_url(191))
    ) $charset_collate;";
    
    // 共享库存记录表
    $inventory_table = $wpdb->prefix . 'wc_flex_inventory_records';
    $inventory_sql = "CREATE TABLE IF NOT EXISTS $inventory_table (
        record_id bigint(20) NOT NULL AUTO_INCREMENT,
        product_id bigint(20) NOT NULL,
        variant_id bigint(20) DEFAULT 0,
        network_store_id bigint(20) NOT NULL,
        shared_quantity int(11) NOT NULL DEFAULT 0,
        reserved_quantity int(11) NOT NULL DEFAULT 0,
        last_synced datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (record_id),
        KEY product_id (product_id),
        KEY network_store_id (network_store_id)
    ) $charset_collate;";
    
    // 库存分配日志表
    $allocation_table = $wpdb->prefix . 'wc_flex_inventory_allocations';
    $allocation_sql = "CREATE TABLE IF NOT EXISTS $allocation_table (
        allocation_id bigint(20) NOT NULL AUTO_INCREMENT,
        order_id bigint(20) NOT NULL,
        product_id bigint(20) NOT NULL,
        allocated_store_id bigint(20) NOT NULL,
        allocated_quantity int(11) NOT NULL,
        allocation_type enum('auto','manual','emergency') DEFAULT 'auto',
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (allocation_id),
        KEY order_id (order_id)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($network_sql);
    dbDelta($inventory_sql);
    dbDelta($allocation_sql);
}

核心功能实现

1. 库存共享网络管理模块

/**
 * 库存共享网络管理类
 * 负责处理店铺的加入、审核和管理
 */
class WC_Flexible_Inventory_Network {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
    }
    
    /**
     * 添加新店铺到共享网络
     * @param array $store_data 店铺数据
     * @return int|false 成功返回店铺ID,失败返回false
     */
    public function add_store_to_network($store_data) {
        $required_fields = ['store_name', 'store_url', 'contact_email'];
        
        foreach ($required_fields as $field) {
            if (empty($store_data[$field])) {
                return false;
            }
        }
        
        // 生成API密钥
        $api_key = $this->generate_api_key();
        
        $table_name = $this->db->prefix . 'wc_flex_inventory_network';
        
        $result = $this->db->insert(
            $table_name,
            [
                'store_name' => sanitize_text_field($store_data['store_name']),
                'store_url' => esc_url_raw($store_data['store_url']),
                'api_key' => $api_key,
                'contact_email' => sanitize_email($store_data['contact_email']),
                'inventory_share_percentage' => isset($store_data['share_percentage']) ? 
                    intval($store_data['share_percentage']) : 100,
                'status' => 'pending'
            ],
            ['%s', '%s', '%s', '%s', '%d', '%s']
        );
        
        if ($result) {
            $store_id = $this->db->insert_id;
            
            // 发送审核通知邮件
            $this->send_approval_notification($store_data, $store_id);
            
            return $store_id;
        }
        
        return false;
    }
    
    /**
     * 生成唯一的API密钥
     * @return string 生成的API密钥
     */
    private function generate_api_key() {
        return 'wc_flex_' . md5(uniqid() . microtime() . wp_rand());
    }
    
    /**
     * 发送审核通知邮件
     */
    private function send_approval_notification($store_data, $store_id) {
        $admin_email = get_option('admin_email');
        $subject = '新的库存共享网络加入申请';
        
        $message = "有新的店铺申请加入库存共享网络:nn";
        $message .= "店铺名称:" . $store_data['store_name'] . "n";
        $message .= "店铺网址:" . $store_data['store_url'] . "n";
        $message .= "联系邮箱:" . $store_data['contact_email'] . "n";
        $message .= "申请时间:" . current_time('mysql') . "nn";
        $message .= "请登录管理后台审核此申请。n";
        $message .= "审核链接:" . admin_url('admin.php?page=wc-flex-inventory&action=review&id=' . $store_id);
        
        wp_mail($admin_email, $subject, $message);
    }
}

2. 实时库存同步系统

/**
 * 实时库存同步管理器
 * 负责处理不同店铺间的库存同步
 */
class WC_Flexible_Inventory_Sync {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
        add_action('wc_flex_inventory_sync_cron', [$this, 'sync_inventory_across_network']);
    }
    
    /**
     * 同步网络中的库存数据
     */
    public function sync_inventory_across_network() {
        // 获取所有活跃的网络店铺
        $network_table = $this->db->prefix . 'wc_flex_inventory_network';
        $active_stores = $this->db->get_results(
            "SELECT * FROM $network_table WHERE status = 'active'"
        );
        
        foreach ($active_stores as $store) {
            $this->sync_with_store($store);
        }
    }
    
    /**
     * 与特定店铺同步库存
     * @param object $store 店铺对象
     */
    private function sync_with_store($store) {
        // 构建API请求
        $api_url = trailingslashit($store->store_url) . 'wp-json/wc-flex-inventory/v1/inventory';
        
        $response = wp_remote_get($api_url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $store->api_key,
                'Content-Type' => 'application/json'
            ],
            'timeout' => 30
        ]);
        
        if (is_wp_error($response)) {
            error_log('库存同步失败: ' . $response->get_error_message());
            return;
        }
        
        $inventory_data = json_decode(wp_remote_retrieve_body($response), true);
        
        if ($inventory_data && isset($inventory_data['inventory'])) {
            $this->update_local_inventory_records($store->network_id, $inventory_data['inventory']);
        }
    }
    
    /**
     * 更新本地库存记录
     */
    private function update_local_inventory_records($store_id, $inventory_items) {
        $table_name = $this->db->prefix . 'wc_flex_inventory_records';
        
        foreach ($inventory_items as $item) {
            $this->db->replace(
                $table_name,
                [
                    'product_id' => intval($item['product_id']),
                    'variant_id' => isset($item['variant_id']) ? intval($item['variant_id']) : 0,
                    'network_store_id' => $store_id,
                    'shared_quantity' => intval($item['quantity']),
                    'last_synced' => current_time('mysql')
                ],
                ['%d', '%d', '%d', '%d', '%s']
            );
        }
    }
    
    /**
     * 获取可用于共享的库存总量
     * @param int $product_id 产品ID
     * @param int $variant_id 变体ID(可选)
     * @return int 可用库存总量
     */
    public function get_available_shared_inventory($product_id, $variant_id = 0) {
        $table_name = $this->db->prefix . 'wc_flex_inventory_records';
        
        $query = $this->db->prepare(
            "SELECT SUM(shared_quantity - reserved_quantity) as total_available 
             FROM $table_name 
             WHERE product_id = %d AND variant_id = %d",
            $product_id,
            $variant_id
        );
        
        $result = $this->db->get_var($query);
        
        return $result ? intval($result) : 0;
    }
}

3. 智能库存分配算法

/**
 * 智能库存分配器
 * 根据预设策略自动分配库存
 */
class WC_Flexible_Inventory_Allocator {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
    }
    
    /**
     * 为订单分配库存
     * @param int $order_id 订单ID
     * @param array $order_items 订单商品列表
     * @return array 分配结果
     */
    public function allocate_inventory_for_order($order_id, $order_items) {
        $allocation_results = [];
        
        foreach ($order_items as $item) {
            $product_id = $item['product_id'];
            $variant_id = isset($item['variation_id']) ? $item['variation_id'] : 0;
            $quantity = $item['quantity'];
            
            // 获取可用的共享库存
            $available_stores = $this->get_available_stores_for_product($product_id, $variant_id);
            
            // 根据分配策略选择店铺
            $allocated_stores = $this->apply_allocation_strategy($available_stores, $quantity);
            
            // 记录分配结果
            foreach ($allocated_stores as $store_allocation) {
                $this->record_allocation(
                    $order_id,
                    $product_id,
                    $store_allocation['store_id'],
                    $store_allocation['quantity']
                );
                
                // 预留库存
                $this->reserve_inventory(
                    $product_id,
                    $variant_id,
                    $store_allocation['store_id'],
                    $store_allocation['quantity']
                );
            }
            
            $allocation_results[$product_id] = $allocated_stores;
        }
        
        return $allocation_results;
    }
    
    /**
     * 获取有可用库存的店铺
     */
    private function get_available_stores_for_product($product_id, $variant_id) {
        $table_name = $this->db->prefix . 'wc_flex_inventory_records';
        
        $query = $this->db->prepare(
            "SELECT r.*, n.store_name, n.store_url 
             FROM $table_name r
             INNER JOIN {$this->db->prefix}wc_flex_inventory_network n 
             ON r.network_store_id = n.network_id
             WHERE r.product_id = %d 
             AND r.variant_id = %d 
             AND (r.shared_quantity - r.reserved_quantity) > 0
             AND n.status = 'active'
             ORDER BY (r.shared_quantity - r.reserved_quantity) DESC",
            $product_id,
            $variant_id
        );
        
        return $this->db->get_results($query, ARRAY_A);
    }
    
    /**
     * 应用分配策略(示例:就近优先策略)
     */
    private function apply_allocation_strategy($available_stores, $required_quantity) {
        $allocations = [];
        $remaining_quantity = $required_quantity;
        
        // 简单策略:按可用库存比例分配
        $total_available = array_sum(array_column($available_stores, 'available'));
        
        foreach ($available_stores as $store) {
            if ($remaining_quantity <= 0) break;
            
            $store_available = $store['shared_quantity'] - $store['reserved_quantity'];
            $store_share = min(
                floor(($store_available / $total_available) * $required_quantity),
                $remaining_quantity
            );
            
            if ($store_share > 0) {
                $allocations[] = [
                    'store_id' => $store['network_store_id'],
                    'quantity' => $store_share
                ];
                $remaining_quantity -= $store_share;
            }
        }
        
        return $allocations;
    }
    
    /**
     * 记录库存分配
     */
    private function record_allocation($order_id, $product_id, $store_id, $quantity) {
        $table_name = $this->db->prefix . 'wc_flex_inventory_allocations';
        
        $this->db->insert(
            $table_name,
            [
                'order_id' => $order_id,
                'product_id' => $product_id,
                'allocated_store_id' => $store_id,
                'allocated_quantity' => $quantity,
                'allocation_type' => 'auto'
            ],
            ['%d', '%d', '%d', '%d', '%s']
        );
    }
}

插件集成与使用

WordPress集成

/**
 * 主插件类
 * 初始化所有组件并集成到WordPress
 */
class WC_Flexible_Inventory_Plugin {
    
    private static $instance = null;
    private $network_manager;
    private $sync_manager;
    private $allocator;
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->init_components();
        $this->setup_hooks();
    }
    
    private function init_components() {
        $this->network_manager = new WC_Flexible_Inventory_Network();
        $this->sync_manager = new WC_Flexible_Inventory_Sync();
        $this->allocator = new WC_Flexible_Inventory_Allocator();
    }
    
    private function setup_hooks() {
        // 插件激活时创建数据表
        register_activation_hook(__FILE__, 'wc_flexible_inventory_create_tables');
        
        // 添加管理菜单
        add_action('admin_menu', [$this, 'add_admin_menu']);
        
        // 集成WooCommerce
        if (class_exists('WooCommerce')) {
            add_filter('woocommerce_product_get_stock_quantity', [$this, 'adjust_stock_quantity'], 10, 2);
            add_action('woocommerce_checkout_order_processed', [$this, 'handle_order_processed'], 10, 3);
        }
        
        // 注册REST API端点
        add_action('rest_api_init', [$this, 'register_rest_endpoints']);
    }
    
    /**
     * 调整显示的库存数量(包含共享库存)
     */
    public function adjust_stock_quantity($quantity, $product) {
        $shared_inventory = $this->sync_manager->get_available_shared_inventory(
            $product->get_id(),
            $product->get_type() === 'variation' ? $product->get_id() : 0
        );
        
        return $quantity + $shared_inventory;
    }
    
    /**
     * 处理订单完成时的库存分配
     */
    public function handle_order_processed($order_id, $posted_data, $order) {
        $order_items = [];
        
        foreach ($order->get_items() as $item) {
            $order_items[] = [
                'product_id' => $item->get_product_id(),
                'variation_id' => $item->get_variation_id(),
                'quantity' => $item->get_quantity()
            ];
        }
        
        $this->allocator->allocate_inventory_for_order($order_id, $order_items);
    }
    
    /**
     * 注册REST API端点供其他店铺访问
     */
    public function register_rest_endpoints() {
        register_rest_route('wc-flex-inventory/v1', '/inventory', [
            'methods' => 'GET',
            'callback' => [$this, 'get_inventory_api'],
            'permission_callback' => [$this, 'check_api_authentication']
        ]);
    }
}

部署与优化建议

性能优化策略

  1. 缓存机制:对频繁查询的库存数据实施缓存
  2. 异步处理:使用队列处理库存同步和分配任务
  3. 数据库索引优化:确保关键

数据库索引优化

/**
 * 数据库优化类
 * 负责优化查询性能和数据管理
 */
class WC_Flexible_Inventory_Optimizer {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
    }
    
    /**
     * 添加性能优化索引
     */
    public function add_performance_indexes() {
        $inventory_table = $this->db->prefix . 'wc_flex_inventory_records';
        $allocations_table = $this->db->prefix . 'wc_flex_inventory_allocations';
        
        // 添加复合索引以提高查询性能
        $indexes = [
            "ALTER TABLE $inventory_table ADD INDEX idx_product_variant (product_id, variant_id)",
            "ALTER TABLE $inventory_table ADD INDEX idx_store_product (network_store_id, product_id)",
            "ALTER TABLE $inventory_table ADD INDEX idx_available_stock (product_id, variant_id, shared_quantity, reserved_quantity)",
            "ALTER TABLE $allocations_table ADD INDEX idx_order_product (order_id, product_id)",
            "ALTER TABLE $allocations_table ADD INDEX idx_store_allocation (allocated_store_id, created_at)"
        ];
        
        foreach ($indexes as $index_sql) {
            $this->db->query($index_sql);
        }
    }
    
    /**
     * 清理历史数据
     * @param int $days_ago 保留多少天前的数据
     */
    public function cleanup_old_data($days_ago = 90) {
        $allocations_table = $this->db->prefix . 'wc_flex_inventory_allocations';
        
        $cutoff_date = date('Y-m-d H:i:s', strtotime("-$days_ago days"));
        
        // 删除旧的分配记录
        $this->db->query(
            $this->db->prepare(
                "DELETE FROM $allocations_table WHERE created_at < %s",
                $cutoff_date
            )
        );
        
        // 优化表
        $this->db->query("OPTIMIZE TABLE $allocations_table");
    }
    
    /**
     * 获取性能统计
     */
    public function get_performance_stats() {
        $stats = [];
        
        $inventory_table = $this->db->prefix . 'wc_flex_inventory_records';
        $allocations_table = $this->db->prefix . 'wc_flex_inventory_allocations';
        
        // 查询表大小
        $stats['inventory_table_size'] = $this->db->get_var(
            "SELECT ROUND((data_length + index_length) / 1024 / 1024, 2) 
             FROM information_schema.TABLES 
             WHERE table_schema = DATABASE() 
             AND table_name = '$inventory_table'"
        );
        
        // 查询记录数量
        $stats['inventory_records'] = $this->db->get_var(
            "SELECT COUNT(*) FROM $inventory_table"
        );
        
        // 查询平均查询时间
        $start_time = microtime(true);
        $this->db->get_var("SELECT 1 FROM $inventory_table LIMIT 1");
        $stats['avg_query_time'] = round((microtime(true) - $start_time) * 1000, 2);
        
        return $stats;
    }
}

前端界面开发

管理后台界面

/**
 * 管理界面类
 * 提供用户友好的管理界面
 */
class WC_Flexible_Inventory_Admin_UI {
    
    public function __construct() {
        add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
    }
    
    /**
     * 加载管理界面资源
     */
    public function enqueue_admin_assets($hook) {
        if (strpos($hook, 'wc-flex-inventory') === false) {
            return;
        }
        
        // 加载CSS样式
        wp_enqueue_style(
            'wc-flex-inventory-admin',
            plugin_dir_url(__FILE__) . 'assets/css/admin.css',
            [],
            '1.0.0'
        );
        
        // 加载JavaScript
        wp_enqueue_script(
            'wc-flex-inventory-admin',
            plugin_dir_url(__FILE__) . 'assets/js/admin.js',
            ['jquery', 'wp-api', 'chartjs'],
            '1.0.0',
            true
        );
        
        // 本地化脚本
        wp_localize_script('wc-flex-inventory-admin', 'wcFlexInventory', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('wc_flex_inventory_nonce'),
            'api_nonce' => wp_create_nonce('wp_rest')
        ]);
    }
    
    /**
     * 渲染网络管理页面
     */
    public function render_network_page() {
        ?>
        <div class="wrap wc-flex-inventory">
            <h1><?php esc_html_e('文创商品柔性库存共享网络', 'wc-flex-inventory'); ?></h1>
            
            <div class="tablenav top">
                <div class="alignleft actions">
                    <button type="button" class="button button-primary" id="add-store-btn">
                        <?php esc_html_e('添加新店铺', 'wc-flex-inventory'); ?>
                    </button>
                </div>
            </div>
            
            <div id="store-network-container">
                <!-- 店铺列表将通过AJAX加载 -->
                <div class="spinner is-active"></div>
            </div>
            
            <!-- 添加店铺模态框 -->
            <div id="add-store-modal" class="modal" style="display:none;">
                <div class="modal-content">
                    <h2><?php esc_html_e('添加新店铺到共享网络', 'wc-flex-inventory'); ?></h2>
                    <form id="add-store-form">
                        <table class="form-table">
                            <tr>
                                <th scope="row">
                                    <label for="store_name"><?php esc_html_e('店铺名称', 'wc-flex-inventory'); ?></label>
                                </th>
                                <td>
                                    <input type="text" id="store_name" name="store_name" class="regular-text" required>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row">
                                    <label for="store_url"><?php esc_html_e('店铺网址', 'wc-flex-inventory'); ?></label>
                                </th>
                                <td>
                                    <input type="url" id="store_url" name="store_url" class="regular-text" required>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row">
                                    <label for="contact_email"><?php esc_html_e('联系邮箱', 'wc-flex-inventory'); ?></label>
                                </th>
                                <td>
                                    <input type="email" id="contact_email" name="contact_email" class="regular-text" required>
                                </td>
                            </tr>
                            <tr>
                                <th scope="row">
                                    <label for="share_percentage"><?php esc_html_e('库存共享比例', 'wc-flex-inventory'); ?></label>
                                </th>
                                <td>
                                    <input type="number" id="share_percentage" name="share_percentage" 
                                           min="0" max="100" value="100" class="small-text">
                                    <span class="description">%</span>
                                    <p class="description">
                                        <?php esc_html_e('该店铺愿意共享的库存百分比', 'wc-flex-inventory'); ?>
                                    </p>
                                </td>
                            </tr>
                        </table>
                        <p class="submit">
                            <button type="submit" class="button button-primary">
                                <?php esc_html_e('提交申请', 'wc-flex-inventory'); ?>
                            </button>
                            <button type="button" class="button button-secondary cancel-modal">
                                <?php esc_html_e('取消', 'wc-flex-inventory'); ?>
                            </button>
                        </p>
                    </form>
                </div>
            </div>
        </div>
        <?php
    }
    
    /**
     * 渲染库存监控页面
     */
    public function render_inventory_monitor() {
        ?>
        <div class="wrap wc-flex-inventory">
            <h1><?php esc_html_e('库存监控与分析', 'wc-flex-inventory'); ?></h1>
            
            <div class="inventory-dashboard">
                <div class="dashboard-row">
                    <div class="dashboard-card">
                        <h3><?php esc_html_e('总共享库存', 'wc-flex-inventory'); ?></h3>
                        <div class="card-value" id="total-shared-inventory">0</div>
                    </div>
                    
                    <div class="dashboard-card">
                        <h3><?php esc_html_e('活跃店铺', 'wc-flex-inventory'); ?></h3>
                        <div class="card-value" id="active-stores">0</div>
                    </div>
                    
                    <div class="dashboard-card">
                        <h3><?php esc_html_e('今日分配', 'wc-flex-inventory'); ?></h3>
                        <div class="card-value" id="today-allocations">0</div>
                    </div>
                    
                    <div class="dashboard-card">
                        <h3><?php esc_html_e('库存周转率', 'wc-flex-inventory'); ?></h3>
                        <div class="card-value" id="inventory-turnover">0%</div>
                    </div>
                </div>
                
                <div class="dashboard-row">
                    <div class="dashboard-chart">
                        <h3><?php esc_html_e('库存分布', 'wc-flex-inventory'); ?></h3>
                        <canvas id="inventory-distribution-chart" width="400" height="200"></canvas>
                    </div>
                    
                    <div class="dashboard-chart">
                        <h3><?php esc_html_e('分配趋势', 'wc-flex-inventory'); ?></h3>
                        <canvas id="allocation-trend-chart" width="400" height="200"></canvas>
                    </div>
                </div>
                
                <div class="dashboard-row">
                    <div class="inventory-alerts">
                        <h3><?php esc_html_e('库存预警', 'wc-flex-inventory'); ?></h3>
                        <div id="inventory-alerts-list">
                            <!-- 预警列表将通过AJAX加载 -->
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }
}

AJAX处理

/**
 * AJAX处理器
 * 处理前端AJAX请求
 */
class WC_Flexible_Inventory_AJAX_Handler {
    
    public function __construct() {
        add_action('wp_ajax_wc_flex_get_stores', [$this, 'get_stores']);
        add_action('wp_ajax_wc_flex_add_store', [$this, 'add_store']);
        add_action('wp_ajax_wc_flex_update_store_status', [$this, 'update_store_status']);
        add_action('wp_ajax_wc_flex_get_inventory_stats', [$this, 'get_inventory_stats']);
    }
    
    /**
     * 获取店铺列表
     */
    public function get_stores() {
        $this->verify_nonce();
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'wc_flex_inventory_network';
        
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        $per_page = 20;
        $offset = ($page - 1) * $per_page;
        
        // 获取店铺数据
        $stores = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM $table_name ORDER BY created_at DESC LIMIT %d OFFSET %d",
                $per_page,
                $offset
            ),
            ARRAY_A
        );
        
        // 获取总数
        $total = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
        
        wp_send_json_success([
            'stores' => $stores,
            'pagination' => [
                'total' => $total,
                'per_page' => $per_page,
                'current_page' => $page,
                'total_pages' => ceil($total / $per_page)
            ]
        ]);
    }
    
    /**
     * 添加新店铺
     */
    public function add_store() {
        $this->verify_nonce();
        
        $store_data = [
            'store_name' => sanitize_text_field($_POST['store_name']),
            'store_url' => esc_url_raw($_POST['store_url']),
            'contact_email' => sanitize_email($_POST['contact_email']),
            'share_percentage' => isset($_POST['share_percentage']) ? 
                intval($_POST['share_percentage']) : 100
        ];
        
        $network_manager = new WC_Flexible_Inventory_Network();
        $result = $network_manager->add_store_to_network($store_data);
        
        if ($result) {
            wp_send_json_success([
                'message' => __('店铺申请已提交,等待审核。', 'wc-flex-inventory'),
                'store_id' => $result
            ]);
        } else {
            wp_send_json_error([
                'message' => __('添加店铺失败,请检查输入数据。', 'wc-flex-inventory')
            ]);
        }
    }
    
    /**
     * 更新店铺状态
     */
    public function update_store_status() {
        $this->verify_nonce();
        
        $store_id = intval($_POST['store_id']);
        $status = sanitize_text_field($_POST['status']);
        
        if (!in_array($status, ['active', 'inactive', 'pending'])) {
            wp_send_json_error(['message' => '无效的状态值']);
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'wc_flex_inventory_network';
        
        $result = $wpdb->update(
            $table_name,
            ['status' => $status],
            ['network_id' => $store_id],
            ['%s'],
            ['%d']
        );
        
        if ($result !== false) {
            // 如果激活店铺,发送通知邮件
            if ($status === 'active') {
                $this->send_activation_email($store_id);
            }
            
            wp_send_json_success(['message' => '店铺状态已更新']);
        } else {
            wp_send_json_error(['message' => '更新失败']);
        }
    }
    
    /**
     * 获取库存统计
     */
    public function get_inventory_stats() {
        $this->verify_nonce();
        
        global $wpdb;
        
        $stats = [];
        
        // 获取总共享库存
        $inventory_table = $wpdb->prefix . 'wc_flex_inventory_records';
        $stats['total_shared'] = $wpdb->get_var(
            "SELECT SUM(shared_quantity) FROM $inventory_table"
        ) ?: 0;
        
        // 获取活跃店铺数量
        $network_table = $wpdb->prefix . 'wc_flex_inventory_network';
        $stats['active_stores'] = $wpdb->get_var(
            "SELECT COUNT(*) FROM $network_table WHERE status = 'active'"
        ) ?: 0;
        
        // 获取今日分配数量
        $allocations_table = $wpdb->prefix . 'wc_flex_inventory_allocations';
        $today = date('Y-m-d');
        $stats['today_allocations'] = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT SUM(allocated_quantity) FROM $allocations_table 
                 WHERE DATE(created_at) = %s",
                $today
            )
        ) ?: 0;
        
        // 获取库存预警
        $stats['alerts'] = $this->get_inventory_alerts();
        
        wp_send_json_success($stats);
    }
    
    /**
     * 验证nonce
     */
    private function verify_nonce() {
        if (!isset($_POST['nonce']) || 
            !wp_verify_nonce($_POST['nonce'], 'wc_flex_inventory_nonce')) {
            wp_send_json_error(['message' => '安全验证失败']);
        }
    }
}

安全与错误处理

安全防护

/**
 * 安全防护类
 * 处理插件安全相关功能
 */
class WC_Flexible_Inventory_Security {
    
    /**
     * 验证API请求
     */
    public static function validate_api_request($request) {
        $api_key = $request->get_header('Authorization');
        
        if (empty($api_key)) {
            return new WP_Error(
                'missing_api_key',
                'API密钥缺失',
                ['status' => 401]
            );
        }
        
        // 移除Bearer前缀
        $api_key = str_replace('Bearer ', '', $api_key);
        
        // 验证API密钥
        global $wpdb;
        $table_name = $wpdb->prefix . 'wc_flex_inventory_network';
        
        $valid = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM $table_name 
                 WHERE api_key = %s AND status = 'active'",
                $api_key
            )
        );
        
        if (!$valid) {
            return new WP_Error(
                'invalid_api_key',
                '无效的API密钥',
                ['status' => 403]
            );
        }
        
        return true;
    }
    
    /**
     * 数据输入验证
     */
    public static function validate_input($data, $rules) {
        $errors = [];
        
        foreach ($rules as $field => $rule) {
            $value = isset($data[$field]) ? $data[$field] : null;
            
            if (in_array('required', $rule) && empty($value)) {
                $errors[$field] = "字段 {$field} 是必填项";
                continue;
            }
            
            if ($value !== null) {
                if (in_array('email', $rule) && !is_email($value)) {
                    $errors[$field] = "字段 {$field} 必须是有效的邮箱地址";
                }
                
                if (in_array('url', $rule) && !filter_var($value, FILTER_VALIDATE_URL)) {
                    $errors[$field] = "字段 {$field} 必须是有效的URL";
                }
                
                if (in_array('numeric', $rule) && !is_numeric($value)) {
                    $errors[$field] = "字段 {$field} 必须是数字";
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5987.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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