文章目录
-
- 在当今电子商务环境中,柔性供应链已成为企业应对市场变化的关键能力。WordPress作为全球最流行的内容管理系统,配合WooCommerce等电商插件,为中小企业提供了强大的电商解决方案。然而,随着订单量增长,异常订单处理成为供应链管理中的痛点。 异常订单包括:库存不足、地址错误、支付异常、高风险欺诈订单等。手动处理这些订单不仅效率低下,而且容易出错。本文将详细介绍如何在WordPress中开发一套智能的异常订单自动处理系统,提升供应链的柔性和响应速度。
-
- 我们的异常订单处理系统将包含以下核心模块: 订单监控模块 - 实时检测异常订单 规则引擎模块 - 定义异常判断规则 处理动作模块 - 执行自动化处理 日志与通知模块 - 记录处理过程和发送通知
- /** * 创建异常订单处理日志表 * 这段代码应该放在插件激活钩子中执行 */ function create_abnormal_orders_table() { global $wpdb; $table_name = $wpdb->prefix . 'abnormal_order_logs'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id bigint(20) NOT NULL AUTO_INCREMENT, order_id bigint(20) NOT NULL, abnormal_type varchar(100) NOT NULL, detection_time datetime DEFAULT CURRENT_TIMESTAMP, action_taken varchar(200) NOT NULL, action_time datetime DEFAULT CURRENT_TIMESTAMP, resolved tinyint(1) DEFAULT 0, notes text, PRIMARY KEY (id), KEY order_id (order_id), KEY abnormal_type (abnormal_type), KEY detection_time (detection_time) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } register_activation_hook(__FILE__, 'create_abnormal_orders_table');
-
- /** * 检测支付异常订单 * @param int $order_id 订单ID * @return array 异常信息数组 */ function detect_payment_abnormalities($order_id) { $order = wc_get_order($order_id); $abnormalities = array(); // 检查订单状态是否为挂起或失败 if ($order->get_status() === 'pending' || $order->get_status() === 'failed') { $payment_method = $order->get_payment_method(); $order_time = $order->get_date_created()->getTimestamp(); $current_time = current_time('timestamp'); // 如果订单创建超过30分钟仍未支付 if (($current_time - $order_time) > 1800) { $abnormalities[] = array( 'type' => 'payment_timeout', 'message' => '订单创建超过30分钟未完成支付', 'severity' => 'medium' ); } // 检查高风险支付方式 $high_risk_methods = array('cod', 'bank_transfer'); if (in_array($payment_method, $high_risk_methods)) { $abnormalities[] = array( 'type' => 'high_risk_payment', 'message' => '使用了高风险支付方式:' . $payment_method, 'severity' => 'high' ); } } return $abnormalities; }
- /** * 检测库存异常 * @param int $order_id 订单ID * @return array 库存异常信息 */ function detect_inventory_abnormalities($order_id) { $order = wc_get_order($order_id); $abnormalities = array(); foreach ($order->get_items() as $item) { $product = $item->get_product(); $product_id = $product->get_id(); $quantity = $item->get_quantity(); // 获取实际库存 $stock_quantity = $product->get_stock_quantity(); // 检查库存是否充足 if ($stock_quantity < $quantity) { $abnormalities[] = array( 'type' => 'insufficient_stock', 'product_id' => $product_id, 'required' => $quantity, 'available' => $stock_quantity, 'message' => sprintf('产品ID %d 库存不足,需要%d,仅剩%d', $product_id, $quantity, $stock_quantity), 'severity' => 'high' ); } // 检查是否为预售产品但未标记 if ($product->get_backorders() === 'no' && $stock_quantity <= 0) { $abnormalities[] = array( 'type' => 'out_of_stock', 'product_id' => $product_id, 'message' => '产品已售罄但仍有订单', 'severity' => 'critical' ); } } return $abnormalities; }
-
- /** * 异常处理规则配置 * 可通过WordPress后台进行配置 */ class Abnormal_Order_Rules { private $rules; public function __construct() { $this->rules = get_option('abnormal_order_rules', $this->get_default_rules()); } /** * 获取默认规则 */ private function get_default_rules() { return array( 'payment_timeout' => array( 'enabled' => true, 'action' => 'send_reminder', 'delay_minutes' => 30, 'max_reminders' => 2, 'final_action' => 'cancel_order' ), 'insufficient_stock' => array( 'enabled' => true, 'action' => 'split_order', 'notify_admin' => true, 'backorder_allowed' => false ), 'high_risk_payment' => array( 'enabled' => true, 'action' => 'hold_for_review', 'notify_admin' => true, 'auto_verify_amount' => 500 // 超过500元需要人工审核 ) ); } /** * 根据异常类型获取处理动作 */ public function get_action_for_abnormality($abnormality_type, $order_amount = 0) { if (!isset($this->rules[$abnormality_type]) || !$this->rules[$abnormality_type]['enabled']) { return 'none'; } $rule = $this->rules[$abnormality_type]; // 特殊逻辑:高风险支付大额订单需要人工审核 if ($abnormality_type === 'high_risk_payment' && $order_amount > $rule['auto_verify_amount']) { return 'manual_review'; } return $rule['action']; } }
- /** * 执行异常订单处理动作 */ class Abnormal_Order_Processor { private $rules_engine; public function __construct() { $this->rules_engine = new Abnormal_Order_Rules(); } /** * 处理异常订单 */ public function process_abnormal_order($order_id, $abnormalities) { $order = wc_get_order($order_id); $order_amount = $order->get_total(); foreach ($abnormalities as $abnormality) { $action = $this->rules_engine->get_action_for_abnormality( $abnormality['type'], $order_amount ); switch ($action) { case 'send_reminder': $this->send_payment_reminder($order_id); break; case 'split_order': $this->split_order_by_stock($order_id); break; case 'hold_for_review': $this->hold_order_for_review($order_id); break; case 'cancel_order': $this->cancel_abnormal_order($order_id, $abnormality['message']); break; case 'manual_review': $this->flag_for_manual_review($order_id, $abnormality); break; } // 记录处理日志 $this->log_abnormality_action($order_id, $abnormality, $action); } } /** * 拆分订单(库存不足时) */ private function split_order_by_stock($order_id) { $order = wc_get_order($order_id); $in_stock_items = array(); $out_of_stock_items = array(); // 分离有库存和无库存的商品 foreach ($order->get_items() as $item_id => $item) { $product = $item->get_product(); if ($product->get_stock_quantity() >= $item->get_quantity()) { $in_stock_items[$item_id] = $item; } else { $out_of_stock_items[$item_id] = $item; } } // 如果有缺货商品,创建新订单 if (!empty($out_of_stock_items)) { $new_order = wc_create_order(array( 'customer_id' => $order->get_customer_id(), 'created_via' => 'abnormal_order_split' )); // 复制客户信息 $new_order->set_address($order->get_address('billing'), 'billing'); $new_order->set_address($order->get_address('shipping'), 'shipping'); // 添加缺货商品到新订单 foreach ($out_of_stock_items as $item_id => $item) { $new_order->add_product($item->get_product(), $item->get_quantity()); } // 更新原订单,移除缺货商品 foreach (array_keys($out_of_stock_items) as $item_id) { $order->remove_item($item_id); } $order->calculate_totals(); $new_order->calculate_totals(); // 保存并添加订单备注 $order->add_order_note('订单已拆分:缺货商品已移至新订单 #' . $new_order->get_id()); $new_order->add_order_note('此订单由订单 #' . $order_id . '拆分而来,原订单库存不足'); $order->save(); $new_order->save(); // 发送通知 $this->send_order_split_notification($order, $new_order); } } }
-
- /** * 基于历史数据的异常预测 * 使用简单的统计方法预测潜在异常 */ class Order_Abnormality_Predictor { /** * 预测订单异常风险评分 */ public function predict_order_risk($order_data) { $risk_score = 0; // 基于历史数据的风险因子 $risk_factors = $this->calculate_risk_factors($order_data); // 地址风险检查 if ($this->is_high_risk_address($order_data['shipping_address'])) { $risk_score += 30; } // 订单金额异常检测 $avg_order_value = $this->get_customer_avg_order_value($order_data['customer_id']); if ($order_data['total'] > $avg_order_value * 3) { $risk_score += 25; } // 购买频率异常 $purchase_frequency = $this->get_purchase_frequency($order_data['customer_id']); if ($purchase_frequency['current_gap'] < $purchase_frequency['avg_gap'] * 0.3) { $risk_score += 20; } // 产品组合异常 if ($this->has_unusual_product_combination($order_data['items'])) { $risk_score += 15; } return min($risk_score, 100); // 限制最大风险分数为100 } /** * 获取客户历史购买频率 */ private function get_purchase_frequency($customer_id) { global $wpdb; $orders = $wpdb->get_col($wpdb->prepare( "SELECT post_date FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_status IN ('wc-completed', 'wc-processing') AND ID IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_customer_user' AND meta_value = %d ) ORDER BY post_date DESC LIMIT 10", $customer_id )); if (count($orders) < 2) { return array('avg_gap' => 30, 'current_gap' => 30); // 默认30天 } // 计算平均购买间隔 $total_gap = 0; for ($i = 0; $i < count($orders) - 1; $i++) { $gap = strtotime($orders[$i]) - strtotime($orders[$i + 1]); $total_gap += $gap / DAY_IN_SECONDS; } $avg_gap = $total_gap / (count($orders) - 1); $current_gap = (time() - strtotime($orders[0])) / DAY_IN_SECONDS; return array( 'avg_gap' => $avg_gap, 'current_gap' => $current_gap ); } }
- /** * 多渠道通知系统 * 支持邮件、短信、企业微信、钉钉等 */ class Multi_Channel_Notifier { /** * 发送异常订单通知 */ public function send_abnormality_notification($order_id, $abnormality, $action_taken) { $order = wc_get_order($order_id); $notification_data = $this->prepare_notification_data($order, $abnormality, $action_taken); // 根据配置发送不同渠道的通知 $channels = get_option('abnormality_notification_channels', array('email')); foreach ($channels as $channel) { switch ($channel) { case 'email': $this->send_email_notification($notification_data); break; case 'sms': $this->send_sms_notification($notification_data); break; case 'wechat_work': $this->send_wechat_work_notification($notification_data); break; case 'dingtalk': $this->send_dingtalk_notification($notification_data); break; case 'slack': $this->send_slack_notification($notification_data); break; } } } /** * 发送企业微信通知 */ private function send_wechat_work_notification($data) { $webhook_url = get_option('wechat_work_webhook_url'); if (empty($webhook_url)) { return false; } $message = array( 'msgtype' => 'markdown', 'markdown' => array( 'content' => "## 异常订单提醒n" . "**订单号**: #{$data['order_id']}n" . "**异常类型**: {$data['abnormality_type']}n" . "**异常描述**: {$data['abnormality_message']}n" . "**处理动作**: {$data['action_taken']}n" . "**订单金额**: ¥{$data['order_total']}n" . "**客户**: {$data['customer_name']}n" . "**检测时间**: {$data['detection_time']}nn" . "[查看订单详情]({$data['admin_order_url']})" ) ); $response = wp_remote_post($webhook_url, array( 'headers' => array('Content-Type' => 'application/json'), 'body' => json_encode($message), 'timeout' => 5 )); return !is_wp_error($response); } /** * 发送钉钉通知 */ private function send_dingtalk_notification($data) { $webhook_url = get_option('dingtalk_webhook_url'); if (empty($webhook_url)) { return false; } $message = array( 'msgtype' => 'markdown', 'markdown' => array( 'title' => '异常订单提醒', 'text' => "### 异常订单提醒n" . "#### 订单信息n" . "- 订单号: #{$data['order_id']}n" . "- 异常类型: {$data['abnormality_type']}n" . "- 处理动作: {$data['action_taken']}n" . "- 订单金额: ¥{$data['order_total']}nn" . "#### 异常详情n" . "{$data['abnormality_message']}nn" . "---n" . "检测时间: {$data['detection_time']}n" . "[点击查看详情]({$data['admin_order_url']})" ), 'at' => array( 'atMobiles' => get_option('dingtalk_at_mobiles', array()), 'isAtAll' => false ) ); $response = wp_remote_post($webhook_url, array( 'headers' => array('Content-Type' => 'application/json'), 'body' => json_encode($message), 'timeout' => 5 )); return !is_wp_error($response); } }
-
- /** * 异常处理性能监控 */ class Performance_Monitor { private $start_time; private $memory_usage; public function __construct() { $this->start_time = microtime(true); $this->memory_usage = memory_get_usage(); } /** * 记录处理性能指标 */ public function log_performance($operation, $order_count) { $end_time = microtime(true); $execution_time = $end_time - $this->start_time; $memory_peak = memory_get_peak_usage() / 1024 / 1024; // 转换为MB global $wpdb; $table_name = $wpdb->prefix . 'abnormality_performance_logs'; $wpdb->insert($table_name, array( 'operation' => $operation, 'order_count' => $order_count, 'execution_time' => $execution_time, 'memory_peak_mb' => $memory_peak, 'log_time' => current_time('mysql') )); // 如果执行时间过长,发送警告 if ($execution_time > 30) { // 超过30秒 $this->send_performance_alert($operation, $execution_time, $order_count); } } /** * 获取性能统计报告 */ public function get_performance_report($days = 7) { global $wpdb; $table_name = $wpdb->prefix . 'abnormality_performance_logs'; $report = $wpdb->get_results($wpdb->prepare( "SELECT operation, COUNT(*) as total_runs, AVG(execution_time) as avg_time, AVG(memory_peak_mb) as avg_memory, MAX(execution_time) as max_time, MIN(execution_time) as min_time, DATE(log_time) as log_date FROM {$table_name} WHERE log_time >= DATE_SUB(NOW(), INTERVAL %d DAY) GROUP BY operation, DATE(log_time) ORDER BY log_date DESC, operation", $days )); return $report; } }
- /** * 批量异常订单处理器 * 优化大量订单处理性能 */ class Batch_Order_Processor { /** * 分批处理异常订单 */ public function process_orders_in_batches($order_ids, $batch_size = 50) { $total_orders = count($order_ids); $batches = array_chunk($order_ids, $batch_size); $results = array( 'processed' => 0, 'abnormalities_found' => 0, 'errors' => 0 ); $monitor = new Performance_Monitor(); foreach ($batches as $batch_index => $batch) { // 每批处理前检查执行时间 if ($this->is_time_limit_approaching()) { $this->log_interrupted_batch($batch_index, $batch_size); break; } foreach ($batch as $order_id) { try { $abnormalities = $this->detect_order_abnormalities($order_id); if (!empty($abnormalities)) { $processor = new Abnormal_Order_Processor(); $processor->process_abnormal_order($order_id, $abnormalities); $results['abnormalities_found']++; } $results['processed']++; // 每处理10个订单休息一下,避免服务器过载 if ($results['processed'] % 10 === 0) { usleep(100000); // 0.1秒 } } catch (Exception $e) { error_log("处理订单 {$order_id} 时出错: " . $e->getMessage()); $results['errors']++; } } // 记录每批处理进度 $this->update_batch_progress($batch_index + 1, count($batches)); } $monitor->log_performance('batch_processing', $total_orders); return $results; } /** * 检查是否接近执行时间限制 */ private function is_time_limit_approaching() { $max_execution_time = ini_get('max_execution_time'); if ($max_execution_time <= 0) { $max_execution_time = 30; // 默认30秒 } $elapsed_time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']; $time_remaining = $max_execution_time - $elapsed_time; // 如果剩余时间少于5秒,停止处理新批次 return $time_remaining < 5; } }
-
- /** * 异常订单处理单元测试 */ class Abnormal_Order_Test extends WP_UnitTestCase { /** * 测试支付超时检测 */ public function test_payment_timeout_detection() { // 创建测试订单 $order = WC_Helper_Order::create_order(); $order->set_status('pending'); $order->set_date_created(strtotime('-35 minutes')); // 超过30分钟 $order->save(); // 检测异常 $abnormalities = detect_payment_abnormalities($order->get_id()); // 验证结果 $this->assertNotEmpty($abnormalities); $this->assertEquals('payment_timeout', $abnormalities[0]['type']); } /** * 测试库存不足检测 */ public function test_insufficient_stock_detection() { // 创建低库存产品 $product = WC_Helper_Product::create_simple_product(); $product->set_stock_quantity(2); $product->save(); // 创建订单,数量为3 $order = WC_Helper_Order::create_order(); $order->add_product($product, 3); $order->save(); // 检测异常 $abnormalities = detect_inventory_abnormalities($order->get_id()); // 验证结果 $this->assertNotEmpty($abnormalities); $this->assertEquals('insufficient_stock', $abnormalities[0]['type']); $this->assertEquals(2, $abnormalities[0]['available']); $this->assertEquals(3, $abnormalities[0]['required']); } /** * 测试订单拆分功能 */ public function test_order_splitting() { // 创建有库存和缺货产品 $in_stock_product = WC_Helper_Product::create_simple_product(); $in_stock_product->set_stock_quantity(10); $in_stock_product->save(); $out_of_stock_product = WC_Helper_Product::create_simple_product(); $out_of_stock_product->set_stock_quantity(0); $out_of_stock_product->save(); // 创建包含两种产品的订单 $order = WC_Helper_Order::create_order(); $order->add_product($in_stock_product, 2); $order->add_product($out_of_stock_product, 1); $order->save(); // 执行拆分 $processor = new Abnormal_Order_Processor(); $abnormalities = array(array('type' => 'insufficient_stock')); $processor->process_abnormal_order($order->get_id(), $abnormalities); // 验证原订单只包含有库存产品 $order = wc_get_order($order->get_id()); $items = $order->get_items(); $this->assertCount(1, $items); // 验证新订单已创建 $new_orders = wc_get_orders(array( 'created_via' => 'abnormal_order_split', 'limit' => 1 )); $this->assertNotEmpty($new_orders); } }
- /** * 异常处理调试工具 */ class Abnormal_Order_Debugger { /** * 显示详细的调试信息 */ public static function debug_order($order_id) { $order = wc_get_order($order_id); if (!$order) { return "订单不存在"; } $debug_info = array( '订单基本信息' => array( '订单号' => $order->get_id(), '订单状态' => $order->get_status(), '订单金额' => $order->get_total(), '支付方式' => $order->get_payment_method(), '创建时间' => $order->get_date_created()->format('Y-m-d H:i:s'), '客户ID' => $order->get_customer_id() ), '异常检测结果' => array(), '处理历史' => array() ); // 运行所有异常检测 $debug_info['异常检测结果']['支付异常'] = detect_payment_abnormalities($order_id); $debug_info['异常检测结果']['库存异常'] = detect_inventory_abnormalities($order_id); // 获取处理历史 global $wpdb; $logs = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}abnormal_order_logs WHERE order_id = %d ORDER BY detection_time DESC", $order_id )); foreach ($logs as $log) { $debug_info['处理历史'][] = array( '异常类型' => $log->abnormal_type, '检测时间' => $log->detection_time, '处理动作' => $log->action_taken, '处理时间' => $log->action_time, '处理状态' => $log->resolved ? '已解决' : '待处理', '备注' => $log->notes ); } // 输出调试信息 echo '<pre>'; print_r($debug_info); echo '</pre>'; // 记录调试日志 self::log_debug_info($order_id, $debug_info); return $debug_info; } /** * 模拟异常场景 */ public static function simulate_abnormal_scenario($scenario_type) { switch ($scenario_type) { case 'payment_timeout':
在当今电子商务环境中,柔性供应链已成为企业应对市场变化的关键能力。WordPress作为全球最流行的内容管理系统,配合WooCommerce等电商插件,为中小企业提供了强大的电商解决方案。然而,随着订单量增长,异常订单处理成为供应链管理中的痛点。
异常订单包括:库存不足、地址错误、支付异常、高风险欺诈订单等。手动处理这些订单不仅效率低下,而且容易出错。本文将详细介绍如何在WordPress中开发一套智能的异常订单自动处理系统,提升供应链的柔性和响应速度。
我们的异常订单处理系统将包含以下核心模块:
- 订单监控模块 - 实时检测异常订单
- 规则引擎模块 - 定义异常判断规则
- 处理动作模块 - 执行自动化处理
- 日志与通知模块 - 记录处理过程和发送通知
/**
* 创建异常订单处理日志表
* 这段代码应该放在插件激活钩子中执行
*/
function create_abnormal_orders_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'abnormal_order_logs';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
order_id bigint(20) NOT NULL,
abnormal_type varchar(100) NOT NULL,
detection_time datetime DEFAULT CURRENT_TIMESTAMP,
action_taken varchar(200) NOT NULL,
action_time datetime DEFAULT CURRENT_TIMESTAMP,
resolved tinyint(1) DEFAULT 0,
notes text,
PRIMARY KEY (id),
KEY order_id (order_id),
KEY abnormal_type (abnormal_type),
KEY detection_time (detection_time)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_abnormal_orders_table');
/**
* 创建异常订单处理日志表
* 这段代码应该放在插件激活钩子中执行
*/
function create_abnormal_orders_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'abnormal_order_logs';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
order_id bigint(20) NOT NULL,
abnormal_type varchar(100) NOT NULL,
detection_time datetime DEFAULT CURRENT_TIMESTAMP,
action_taken varchar(200) NOT NULL,
action_time datetime DEFAULT CURRENT_TIMESTAMP,
resolved tinyint(1) DEFAULT 0,
notes text,
PRIMARY KEY (id),
KEY order_id (order_id),
KEY abnormal_type (abnormal_type),
KEY detection_time (detection_time)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_abnormal_orders_table');
/**
* 检测支付异常订单
* @param int $order_id 订单ID
* @return array 异常信息数组
*/
function detect_payment_abnormalities($order_id) {
$order = wc_get_order($order_id);
$abnormalities = array();
// 检查订单状态是否为挂起或失败
if ($order->get_status() === 'pending' || $order->get_status() === 'failed') {
$payment_method = $order->get_payment_method();
$order_time = $order->get_date_created()->getTimestamp();
$current_time = current_time('timestamp');
// 如果订单创建超过30分钟仍未支付
if (($current_time - $order_time) > 1800) {
$abnormalities[] = array(
'type' => 'payment_timeout',
'message' => '订单创建超过30分钟未完成支付',
'severity' => 'medium'
);
}
// 检查高风险支付方式
$high_risk_methods = array('cod', 'bank_transfer');
if (in_array($payment_method, $high_risk_methods)) {
$abnormalities[] = array(
'type' => 'high_risk_payment',
'message' => '使用了高风险支付方式:' . $payment_method,
'severity' => 'high'
);
}
}
return $abnormalities;
}
/**
* 检测支付异常订单
* @param int $order_id 订单ID
* @return array 异常信息数组
*/
function detect_payment_abnormalities($order_id) {
$order = wc_get_order($order_id);
$abnormalities = array();
// 检查订单状态是否为挂起或失败
if ($order->get_status() === 'pending' || $order->get_status() === 'failed') {
$payment_method = $order->get_payment_method();
$order_time = $order->get_date_created()->getTimestamp();
$current_time = current_time('timestamp');
// 如果订单创建超过30分钟仍未支付
if (($current_time - $order_time) > 1800) {
$abnormalities[] = array(
'type' => 'payment_timeout',
'message' => '订单创建超过30分钟未完成支付',
'severity' => 'medium'
);
}
// 检查高风险支付方式
$high_risk_methods = array('cod', 'bank_transfer');
if (in_array($payment_method, $high_risk_methods)) {
$abnormalities[] = array(
'type' => 'high_risk_payment',
'message' => '使用了高风险支付方式:' . $payment_method,
'severity' => 'high'
);
}
}
return $abnormalities;
}
/**
* 检测库存异常
* @param int $order_id 订单ID
* @return array 库存异常信息
*/
function detect_inventory_abnormalities($order_id) {
$order = wc_get_order($order_id);
$abnormalities = array();
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$product_id = $product->get_id();
$quantity = $item->get_quantity();
// 获取实际库存
$stock_quantity = $product->get_stock_quantity();
// 检查库存是否充足
if ($stock_quantity < $quantity) {
$abnormalities[] = array(
'type' => 'insufficient_stock',
'product_id' => $product_id,
'required' => $quantity,
'available' => $stock_quantity,
'message' => sprintf('产品ID %d 库存不足,需要%d,仅剩%d',
$product_id, $quantity, $stock_quantity),
'severity' => 'high'
);
}
// 检查是否为预售产品但未标记
if ($product->get_backorders() === 'no' && $stock_quantity <= 0) {
$abnormalities[] = array(
'type' => 'out_of_stock',
'product_id' => $product_id,
'message' => '产品已售罄但仍有订单',
'severity' => 'critical'
);
}
}
return $abnormalities;
}
/**
* 检测库存异常
* @param int $order_id 订单ID
* @return array 库存异常信息
*/
function detect_inventory_abnormalities($order_id) {
$order = wc_get_order($order_id);
$abnormalities = array();
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$product_id = $product->get_id();
$quantity = $item->get_quantity();
// 获取实际库存
$stock_quantity = $product->get_stock_quantity();
// 检查库存是否充足
if ($stock_quantity < $quantity) {
$abnormalities[] = array(
'type' => 'insufficient_stock',
'product_id' => $product_id,
'required' => $quantity,
'available' => $stock_quantity,
'message' => sprintf('产品ID %d 库存不足,需要%d,仅剩%d',
$product_id, $quantity, $stock_quantity),
'severity' => 'high'
);
}
// 检查是否为预售产品但未标记
if ($product->get_backorders() === 'no' && $stock_quantity <= 0) {
$abnormalities[] = array(
'type' => 'out_of_stock',
'product_id' => $product_id,
'message' => '产品已售罄但仍有订单',
'severity' => 'critical'
);
}
}
return $abnormalities;
}
/**
* 异常处理规则配置
* 可通过WordPress后台进行配置
*/
class Abnormal_Order_Rules {
private $rules;
public function __construct() {
$this->rules = get_option('abnormal_order_rules', $this->get_default_rules());
}
/**
* 获取默认规则
*/
private function get_default_rules() {
return array(
'payment_timeout' => array(
'enabled' => true,
'action' => 'send_reminder',
'delay_minutes' => 30,
'max_reminders' => 2,
'final_action' => 'cancel_order'
),
'insufficient_stock' => array(
'enabled' => true,
'action' => 'split_order',
'notify_admin' => true,
'backorder_allowed' => false
),
'high_risk_payment' => array(
'enabled' => true,
'action' => 'hold_for_review',
'notify_admin' => true,
'auto_verify_amount' => 500 // 超过500元需要人工审核
)
);
}
/**
* 根据异常类型获取处理动作
*/
public function get_action_for_abnormality($abnormality_type, $order_amount = 0) {
if (!isset($this->rules[$abnormality_type]) || !$this->rules[$abnormality_type]['enabled']) {
return 'none';
}
$rule = $this->rules[$abnormality_type];
// 特殊逻辑:高风险支付大额订单需要人工审核
if ($abnormality_type === 'high_risk_payment' &&
$order_amount > $rule['auto_verify_amount']) {
return 'manual_review';
}
return $rule['action'];
}
}
/**
* 异常处理规则配置
* 可通过WordPress后台进行配置
*/
class Abnormal_Order_Rules {
private $rules;
public function __construct() {
$this->rules = get_option('abnormal_order_rules', $this->get_default_rules());
}
/**
* 获取默认规则
*/
private function get_default_rules() {
return array(
'payment_timeout' => array(
'enabled' => true,
'action' => 'send_reminder',
'delay_minutes' => 30,
'max_reminders' => 2,
'final_action' => 'cancel_order'
),
'insufficient_stock' => array(
'enabled' => true,
'action' => 'split_order',
'notify_admin' => true,
'backorder_allowed' => false
),
'high_risk_payment' => array(
'enabled' => true,
'action' => 'hold_for_review',
'notify_admin' => true,
'auto_verify_amount' => 500 // 超过500元需要人工审核
)
);
}
/**
* 根据异常类型获取处理动作
*/
public function get_action_for_abnormality($abnormality_type, $order_amount = 0) {
if (!isset($this->rules[$abnormality_type]) || !$this->rules[$abnormality_type]['enabled']) {
return 'none';
}
$rule = $this->rules[$abnormality_type];
// 特殊逻辑:高风险支付大额订单需要人工审核
if ($abnormality_type === 'high_risk_payment' &&
$order_amount > $rule['auto_verify_amount']) {
return 'manual_review';
}
return $rule['action'];
}
}
/**
* 执行异常订单处理动作
*/
class Abnormal_Order_Processor {
private $rules_engine;
public function __construct() {
$this->rules_engine = new Abnormal_Order_Rules();
}
/**
* 处理异常订单
*/
public function process_abnormal_order($order_id, $abnormalities) {
$order = wc_get_order($order_id);
$order_amount = $order->get_total();
foreach ($abnormalities as $abnormality) {
$action = $this->rules_engine->get_action_for_abnormality(
$abnormality['type'],
$order_amount
);
switch ($action) {
case 'send_reminder':
$this->send_payment_reminder($order_id);
break;
case 'split_order':
$this->split_order_by_stock($order_id);
break;
case 'hold_for_review':
$this->hold_order_for_review($order_id);
break;
case 'cancel_order':
$this->cancel_abnormal_order($order_id, $abnormality['message']);
break;
case 'manual_review':
$this->flag_for_manual_review($order_id, $abnormality);
break;
}
// 记录处理日志
$this->log_abnormality_action($order_id, $abnormality, $action);
}
}
/**
* 拆分订单(库存不足时)
*/
private function split_order_by_stock($order_id) {
$order = wc_get_order($order_id);
$in_stock_items = array();
$out_of_stock_items = array();
// 分离有库存和无库存的商品
foreach ($order->get_items() as $item_id => $item) {
$product = $item->get_product();
if ($product->get_stock_quantity() >= $item->get_quantity()) {
$in_stock_items[$item_id] = $item;
} else {
$out_of_stock_items[$item_id] = $item;
}
}
// 如果有缺货商品,创建新订单
if (!empty($out_of_stock_items)) {
$new_order = wc_create_order(array(
'customer_id' => $order->get_customer_id(),
'created_via' => 'abnormal_order_split'
));
// 复制客户信息
$new_order->set_address($order->get_address('billing'), 'billing');
$new_order->set_address($order->get_address('shipping'), 'shipping');
// 添加缺货商品到新订单
foreach ($out_of_stock_items as $item_id => $item) {
$new_order->add_product($item->get_product(), $item->get_quantity());
}
// 更新原订单,移除缺货商品
foreach (array_keys($out_of_stock_items) as $item_id) {
$order->remove_item($item_id);
}
$order->calculate_totals();
$new_order->calculate_totals();
// 保存并添加订单备注
$order->add_order_note('订单已拆分:缺货商品已移至新订单 #' . $new_order->get_id());
$new_order->add_order_note('此订单由订单 #' . $order_id . '拆分而来,原订单库存不足');
$order->save();
$new_order->save();
// 发送通知
$this->send_order_split_notification($order, $new_order);
}
}
}
/**
* 执行异常订单处理动作
*/
class Abnormal_Order_Processor {
private $rules_engine;
public function __construct() {
$this->rules_engine = new Abnormal_Order_Rules();
}
/**
* 处理异常订单
*/
public function process_abnormal_order($order_id, $abnormalities) {
$order = wc_get_order($order_id);
$order_amount = $order->get_total();
foreach ($abnormalities as $abnormality) {
$action = $this->rules_engine->get_action_for_abnormality(
$abnormality['type'],
$order_amount
);
switch ($action) {
case 'send_reminder':
$this->send_payment_reminder($order_id);
break;
case 'split_order':
$this->split_order_by_stock($order_id);
break;
case 'hold_for_review':
$this->hold_order_for_review($order_id);
break;
case 'cancel_order':
$this->cancel_abnormal_order($order_id, $abnormality['message']);
break;
case 'manual_review':
$this->flag_for_manual_review($order_id, $abnormality);
break;
}
// 记录处理日志
$this->log_abnormality_action($order_id, $abnormality, $action);
}
}
/**
* 拆分订单(库存不足时)
*/
private function split_order_by_stock($order_id) {
$order = wc_get_order($order_id);
$in_stock_items = array();
$out_of_stock_items = array();
// 分离有库存和无库存的商品
foreach ($order->get_items() as $item_id => $item) {
$product = $item->get_product();
if ($product->get_stock_quantity() >= $item->get_quantity()) {
$in_stock_items[$item_id] = $item;
} else {
$out_of_stock_items[$item_id] = $item;
}
}
// 如果有缺货商品,创建新订单
if (!empty($out_of_stock_items)) {
$new_order = wc_create_order(array(
'customer_id' => $order->get_customer_id(),
'created_via' => 'abnormal_order_split'
));
// 复制客户信息
$new_order->set_address($order->get_address('billing'), 'billing');
$new_order->set_address($order->get_address('shipping'), 'shipping');
// 添加缺货商品到新订单
foreach ($out_of_stock_items as $item_id => $item) {
$new_order->add_product($item->get_product(), $item->get_quantity());
}
// 更新原订单,移除缺货商品
foreach (array_keys($out_of_stock_items) as $item_id) {
$order->remove_item($item_id);
}
$order->calculate_totals();
$new_order->calculate_totals();
// 保存并添加订单备注
$order->add_order_note('订单已拆分:缺货商品已移至新订单 #' . $new_order->get_id());
$new_order->add_order_note('此订单由订单 #' . $order_id . '拆分而来,原订单库存不足');
$order->save();
$new_order->save();
// 发送通知
$this->send_order_split_notification($order, $new_order);
}
}
}
/**
* 设置异常订单扫描定时任务
*/
class Abnormal_Order_Scheduler {
public function __construct() {
// 添加自定义定时任务间隔
add_filter('cron_schedules', array($this, 'add_custom_schedules'));
// 设置定时任务钩子
add_action('abnormal_order_scan_event', array($this, 'scan_abnormal_orders'));
// 激活插件时安排定时任务
register_activation_hook(__FILE__, array($this, 'schedule_abnormal_order_scan'));
// 停用插件时清除定时任务
register_deactivation_hook(__FILE__, array($this, 'clear_abnormal_order_scan'));
}
/**
* 添加自定义调度间隔
*/
public function add_custom_schedules($schedules) {
$schedules['every_10_minutes'] = array(
'interval' => 600, // 10分钟
'display' => __('每10分钟')
);
$schedules['every_hour'] = array(
'interval' => 3600, // 1小时
'display' => __('每小时')
);
return $schedules;
}
/**
* 安排定时扫描任务
*/
public function schedule_abnormal_order_scan() {
if (!wp_next_scheduled('abnormal_order_scan_event')) {
wp_schedule_event(time(), 'every_10_minutes', 'abnormal_order_scan_event');
}
}
/**
* 执行异常订单扫描
*/
public function scan_abnormal_orders() {
global $wpdb;
// 获取最近2小时内的订单
$two_hours_ago = date('Y-m-d H:i:s', strtotime('-2 hours'));
$order_ids = $wpdb->get_col($wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = 'shop_order'
AND post_date >= %s
AND post_status IN ('wc-pending', 'wc-processing', 'wc-on-hold')",
$two_hours_ago
));
$processor = new Abnormal_Order_Processor();
foreach ($order_ids as $order_id) {
$abnormalities = array();
// 检测各种异常
$abnormalities = array_merge(
$abnormalities,
detect_payment_abnormalities($order_id)
);
$abnormalities = array_merge(
$abnormalities,
detect_inventory_abnormalities($order_id)
);
// 如果有异常,进行处理
if (!empty($abnormalities)) {
$processor->process_abnormal_order($order_id, $abnormalities);
}
}
}
}
/**
* 设置异常订单扫描定时任务
*/
class Abnormal_Order_Scheduler {
public function __construct() {
// 添加自定义定时任务间隔
add_filter('cron_schedules', array($this, 'add_custom_schedules'));
// 设置定时任务钩子
add_action('abnormal_order_scan_event', array($this, 'scan_abnormal_orders'));
// 激活插件时安排定时任务
register_activation_hook(__FILE__, array($this, 'schedule_abnormal_order_scan'));
// 停用插件时清除定时任务
register_deactivation_hook(__FILE__, array($this, 'clear_abnormal_order_scan'));
}
/**
* 添加自定义调度间隔
*/
public function add_custom_schedules($schedules) {
$schedules['every_10_minutes'] = array(
'interval' => 600, // 10分钟
'display' => __('每10分钟')
);
$schedules['every_hour'] = array(
'interval' => 3600, // 1小时
'display' => __('每小时')
);
return $schedules;
}
/**
* 安排定时扫描任务
*/
public function schedule_abnormal_order_scan() {
if (!wp_next_scheduled('abnormal_order_scan_event')) {
wp_schedule_event(time(), 'every_10_minutes', 'abnormal_order_scan_event');
}
}
/**
* 执行异常订单扫描
*/
public function scan_abnormal_orders() {
global $wpdb;
// 获取最近2小时内的订单
$two_hours_ago = date('Y-m-d H:i:s', strtotime('-2 hours'));
$order_ids = $wpdb->get_col($wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = 'shop_order'
AND post_date >= %s
AND post_status IN ('wc-pending', 'wc-processing', 'wc-on-hold')",
$two_hours_ago
));
$processor = new Abnormal_Order_Processor();
foreach ($order_ids as $order_id) {
$abnormalities = array();
// 检测各种异常
$abnormalities = array_merge(
$abnormalities,
detect_payment_abnormalities($order_id)
);
$abnormalities = array_merge(
$abnormalities,
detect_inventory_abnormalities($order_id)
);
// 如果有异常,进行处理
if (!empty($abnormalities)) {
$processor->process_abnormal_order($order_id, $abnormalities);
}
}
}
}
/**
* 添加异常订单管理页面
*/
class Abnormal_Orders_Admin {
public function __construct() {
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_submenu_page(
'woocommerce',
'异常订单管理',
'异常订单',
'manage_woocommerce',
'abnormal-orders',
array($this, 'render_admin_page')
);
}
/**
* 渲染管理页面
*/
public function render_admin_page() {
global $wpdb;
// 获取异常订单统计
$stats = $wpdb->get_row("
SELECT
COUNT(*) as total,
SUM(CASE WHEN resolved = 0 THEN 1 ELSE 0 END) as pending,
SUM(CASE WHEN resolved = 1 THEN 1 ELSE 0 END) as resolved
FROM {$wpdb->prefix}abnormal_order_logs
WHERE detection_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
");
// 获取最近的异常订单
$recent_abnormalities = $wpdb->get_results("
SELECT l.*, p.post_title as order_title
FROM {$wpdb->prefix}abnormal_order_logs l
LEFT JOIN {$wpdb->posts} p ON l.order_id = p.ID
ORDER BY l.detection_time DESC
LIMIT 20
");
?>
<div class="wrap">
<h1>异常订单管理系统</h1>
<div class="abnormal-stats">
<div class="stat-card">
<h3>近7天异常订单</h3>
<p class="stat-number"><?php echo $stats->total; ?></p>
</div>
<div class="stat-card">
<h3>待处理</h3>
<p class="stat-number pending"><?php echo $stats->pending; ?></p>
</div>
<div class="stat-card">
<h3>已处理</h3>
<p class="stat-number resolved"><?php echo $stats->resolved; ?></p>
</div>
</div>
<h2>最近异常订单</h2>
<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>
<?php foreach ($recent_abnormalities as $log): ?>
<tr>
<td>
<a href="<?php echo admin_url('post.php?post=' . $log->order_id . '&action=edit'); ?>">
#<?php echo $log->order_id; ?> - <?php echo $log->order_title; ?>
</a>
</td>
<td><?php echo $this->get_abnormality_label($log->abnormal_type); ?></td>
<td><?php echo $log->detection_time; ?></td>
<td><?php echo $log->action_taken; ?></td>
<td>
<?php if ($log->resolved): ?>
<span class="dashicons dashicons-yes" style="color:green"></span> 已解决
<?php else: ?>
<span class="dashicons dashicons-warning" style="color:orange"></span> 待处理
<?php endif; ?>
</td>
<td>
<a href="#" class="button button-small view-log-details"
data-log-id="<?php echo $log->id; ?>">
详情
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php
}
}
/**
* 添加异常订单管理页面
*/
class Abnormal_Orders_Admin {
public function __construct() {
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_submenu_page(
'woocommerce',
'异常订单管理',
'异常订单',
'manage_woocommerce',
'abnormal-orders',
array($this, 'render_admin_page')
);
}
/**
* 渲染管理页面
*/
public function render_admin_page() {
global $wpdb;
// 获取异常订单统计
$stats = $wpdb->get_row("
SELECT
COUNT(*) as total,
SUM(CASE WHEN resolved = 0 THEN 1 ELSE 0 END) as pending,
SUM(CASE WHEN resolved = 1 THEN 1 ELSE 0 END) as resolved
FROM {$wpdb->prefix}abnormal_order_logs
WHERE detection_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
");
// 获取最近的异常订单
$recent_abnormalities = $wpdb->get_results("
SELECT l.*, p.post_title as order_title
FROM {$wpdb->prefix}abnormal_order_logs l
LEFT JOIN {$wpdb->posts} p ON l.order_id = p.ID
ORDER BY l.detection_time DESC
LIMIT 20
");
?>
<div class="wrap">
<h1>异常订单管理系统</h1>
<div class="abnormal-stats">
<div class="stat-card">
<h3>近7天异常订单</h3>
<p class="stat-number"><?php echo $stats->total; ?></p>
</div>
<div class="stat-card">
<h3>待处理</h3>
<p class="stat-number pending"><?php echo $stats->pending; ?></p>
</div>
<div class="stat-card">
<h3>已处理</h3>
<p class="stat-number resolved"><?php echo $stats->resolved; ?></p>
</div>
</div>
<h2>最近异常订单</h2>
<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>
<?php foreach ($recent_abnormalities as $log): ?>
<tr>
<td>
<a href="<?php echo admin_url('post.php?post=' . $log->order_id . '&action=edit'); ?>">
#<?php echo $log->order_id; ?> - <?php echo $log->order_title; ?>
</a>
</td>
<td><?php echo $this->get_abnormality_label($log->abnormal_type); ?></td>
<td><?php echo $log->detection_time; ?></td>
<td><?php echo $log->action_taken; ?></td>
<td>
<?php if ($log->resolved): ?>
<span class="dashicons dashicons-yes" style="color:green"></span> 已解决
<?php else: ?>
<span class="dashicons dashicons-warning" style="color:orange"></span> 待处理
<?php endif; ?>
</td>
<td>
<a href="#" class="button button-small view-log-details"
data-log-id="<?php echo $log->id; ?>">
详情
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php
}
}
- 将上述代码整合到WordPress插件中
- 在测试环境中验证所有功能
- 配置异常处理规则
- 设置适当的扫描频率
- 监控系统性能和处理效果
- 使用WordPress Transients
缓存频繁查询的订单数据
- 为大型订单数据库添加索引优化
- 实现分批处理避免超时
- 使用异步处理提高响应速度
- 所有用户输入必须进行验证和清理
- 敏感操作需要权限检查
- 日志记录要避免存储敏感信息
- 定期备份异常处理规则和日志
/**
* 基于历史数据的异常预测
* 使用简单的统计方法预测潜在异常
*/
class Order_Abnormality_Predictor {
/**
* 预测订单异常风险评分
*/
public function predict_order_risk($order_data) {
$risk_score = 0;
// 基于历史数据的风险因子
$risk_factors = $this->calculate_risk_factors($order_data);
// 地址风险检查
if ($this->is_high_risk_address($order_data['shipping_address'])) {
$risk_score += 30;
}
// 订单金额异常检测
$avg_order_value = $this->get_customer_avg_order_value($order_data['customer_id']);
if ($order_data['total'] > $avg_order_value * 3) {
$risk_score += 25;
}
// 购买频率异常
$purchase_frequency = $this->get_purchase_frequency($order_data['customer_id']);
if ($purchase_frequency['current_gap'] < $purchase_frequency['avg_gap'] * 0.3) {
$risk_score += 20;
}
// 产品组合异常
if ($this->has_unusual_product_combination($order_data['items'])) {
$risk_score += 15;
}
return min($risk_score, 100); // 限制最大风险分数为100
}
/**
* 获取客户历史购买频率
*/
private function get_purchase_frequency($customer_id) {
global $wpdb;
$orders = $wpdb->get_col($wpdb->prepare(
"SELECT post_date
FROM {$wpdb->posts}
WHERE post_type = 'shop_order'
AND post_status IN ('wc-completed', 'wc-processing')
AND ID IN (
SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_customer_user'
AND meta_value = %d
)
ORDER BY post_date DESC
LIMIT 10",
$customer_id
));
if (count($orders) < 2) {
return array('avg_gap' => 30, 'current_gap' => 30); // 默认30天
}
// 计算平均购买间隔
$total_gap = 0;
for ($i = 0; $i < count($orders) - 1; $i++) {
$gap = strtotime($orders[$i]) - strtotime($orders[$i + 1]);
$total_gap += $gap / DAY_IN_SECONDS;
}
$avg_gap = $total_gap / (count($orders) - 1);
$current_gap = (time() - strtotime($orders[0])) / DAY_IN_SECONDS;
return array(
'avg_gap' => $avg_gap,
'current_gap' => $current_gap
);
}
}
/**
* 基于历史数据的异常预测
* 使用简单的统计方法预测潜在异常
*/
class Order_Abnormality_Predictor {
/**
* 预测订单异常风险评分
*/
public function predict_order_risk($order_data) {
$risk_score = 0;
// 基于历史数据的风险因子
$risk_factors = $this->calculate_risk_factors($order_data);
// 地址风险检查
if ($this->is_high_risk_address($order_data['shipping_address'])) {
$risk_score += 30;
}
// 订单金额异常检测
$avg_order_value = $this->get_customer_avg_order_value($order_data['customer_id']);
if ($order_data['total'] > $avg_order_value * 3) {
$risk_score += 25;
}
// 购买频率异常
$purchase_frequency = $this->get_purchase_frequency($order_data['customer_id']);
if ($purchase_frequency['current_gap'] < $purchase_frequency['avg_gap'] * 0.3) {
$risk_score += 20;
}
// 产品组合异常
if ($this->has_unusual_product_combination($order_data['items'])) {
$risk_score += 15;
}
return min($risk_score, 100); // 限制最大风险分数为100
}
/**
* 获取客户历史购买频率
*/
private function get_purchase_frequency($customer_id) {
global $wpdb;
$orders = $wpdb->get_col($wpdb->prepare(
"SELECT post_date
FROM {$wpdb->posts}
WHERE post_type = 'shop_order'
AND post_status IN ('wc-completed', 'wc-processing')
AND ID IN (
SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_customer_user'
AND meta_value = %d
)
ORDER BY post_date DESC
LIMIT 10",
$customer_id
));
if (count($orders) < 2) {
return array('avg_gap' => 30, 'current_gap' => 30); // 默认30天
}
// 计算平均购买间隔
$total_gap = 0;
for ($i = 0; $i < count($orders) - 1; $i++) {
$gap = strtotime($orders[$i]) - strtotime($orders[$i + 1]);
$total_gap += $gap / DAY_IN_SECONDS;
}
$avg_gap = $total_gap / (count($orders) - 1);
$current_gap = (time() - strtotime($orders[0])) / DAY_IN_SECONDS;
return array(
'avg_gap' => $avg_gap,
'current_gap' => $current_gap
);
}
}
/**
* 多渠道通知系统
* 支持邮件、短信、企业微信、钉钉等
*/
class Multi_Channel_Notifier {
/**
* 发送异常订单通知
*/
public function send_abnormality_notification($order_id, $abnormality, $action_taken) {
$order = wc_get_order($order_id);
$notification_data = $this->prepare_notification_data($order, $abnormality, $action_taken);
// 根据配置发送不同渠道的通知
$channels = get_option('abnormality_notification_channels', array('email'));
foreach ($channels as $channel) {
switch ($channel) {
case 'email':
$this->send_email_notification($notification_data);
break;
case 'sms':
$this->send_sms_notification($notification_data);
break;
case 'wechat_work':
$this->send_wechat_work_notification($notification_data);
break;
case 'dingtalk':
$this->send_dingtalk_notification($notification_data);
break;
case 'slack':
$this->send_slack_notification($notification_data);
break;
}
}
}
/**
* 发送企业微信通知
*/
private function send_wechat_work_notification($data) {
$webhook_url = get_option('wechat_work_webhook_url');
if (empty($webhook_url)) {
return false;
}
$message = array(
'msgtype' => 'markdown',
'markdown' => array(
'content' => "## 异常订单提醒n" .
"**订单号**: #{$data['order_id']}n" .
"**异常类型**: {$data['abnormality_type']}n" .
"**异常描述**: {$data['abnormality_message']}n" .
"**处理动作**: {$data['action_taken']}n" .
"**订单金额**: ¥{$data['order_total']}n" .
"**客户**: {$data['customer_name']}n" .
"**检测时间**: {$data['detection_time']}nn" .
"[查看订单详情]({$data['admin_order_url']})"
)
);
$response = wp_remote_post($webhook_url, array(
'headers' => array('Content-Type' => 'application/json'),
'body' => json_encode($message),
'timeout' => 5
));
return !is_wp_error($response);
}
/**
* 发送钉钉通知
*/
private function send_dingtalk_notification($data) {
$webhook_url = get_option('dingtalk_webhook_url');
if (empty($webhook_url)) {
return false;
}
$message = array(
'msgtype' => 'markdown',
'markdown' => array(
'title' => '异常订单提醒',
'text' => "### 异常订单提醒n" .
"#### 订单信息n" .
"- 订单号: #{$data['order_id']}n" .
"- 异常类型: {$data['abnormality_type']}n" .
"- 处理动作: {$data['action_taken']}n" .
"- 订单金额: ¥{$data['order_total']}nn" .
"#### 异常详情n" .
"{$data['abnormality_message']}nn" .
"---n" .
"检测时间: {$data['detection_time']}n" .
"[点击查看详情]({$data['admin_order_url']})"
),
'at' => array(
'atMobiles' => get_option('dingtalk_at_mobiles', array()),
'isAtAll' => false
)
);
$response = wp_remote_post($webhook_url, array(
'headers' => array('Content-Type' => 'application/json'),
'body' => json_encode($message),
'timeout' => 5
));
return !is_wp_error($response);
}
}
/**
* 多渠道通知系统
* 支持邮件、短信、企业微信、钉钉等
*/
class Multi_Channel_Notifier {
/**
* 发送异常订单通知
*/
public function send_abnormality_notification($order_id, $abnormality, $action_taken) {
$order = wc_get_order($order_id);
$notification_data = $this->prepare_notification_data($order, $abnormality, $action_taken);
// 根据配置发送不同渠道的通知
$channels = get_option('abnormality_notification_channels', array('email'));
foreach ($channels as $channel) {
switch ($channel) {
case 'email':
$this->send_email_notification($notification_data);
break;
case 'sms':
$this->send_sms_notification($notification_data);
break;
case 'wechat_work':
$this->send_wechat_work_notification($notification_data);
break;
case 'dingtalk':
$this->send_dingtalk_notification($notification_data);
break;
case 'slack':
$this->send_slack_notification($notification_data);
break;
}
}
}
/**
* 发送企业微信通知
*/
private function send_wechat_work_notification($data) {
$webhook_url = get_option('wechat_work_webhook_url');
if (empty($webhook_url)) {
return false;
}
$message = array(
'msgtype' => 'markdown',
'markdown' => array(
'content' => "## 异常订单提醒n" .
"**订单号**: #{$data['order_id']}n" .
"**异常类型**: {$data['abnormality_type']}n" .
"**异常描述**: {$data['abnormality_message']}n" .
"**处理动作**: {$data['action_taken']}n" .
"**订单金额**: ¥{$data['order_total']}n" .
"**客户**: {$data['customer_name']}n" .
"**检测时间**: {$data['detection_time']}nn" .
"[查看订单详情]({$data['admin_order_url']})"
)
);
$response = wp_remote_post($webhook_url, array(
'headers' => array('Content-Type' => 'application/json'),
'body' => json_encode($message),
'timeout' => 5
));
return !is_wp_error($response);
}
/**
* 发送钉钉通知
*/
private function send_dingtalk_notification($data) {
$webhook_url = get_option('dingtalk_webhook_url');
if (empty($webhook_url)) {
return false;
}
$message = array(
'msgtype' => 'markdown',
'markdown' => array(
'title' => '异常订单提醒',
'text' => "### 异常订单提醒n" .
"#### 订单信息n" .
"- 订单号: #{$data['order_id']}n" .
"- 异常类型: {$data['abnormality_type']}n" .
"- 处理动作: {$data['action_taken']}n" .
"- 订单金额: ¥{$data['order_total']}nn" .
"#### 异常详情n" .
"{$data['abnormality_message']}nn" .
"---n" .
"检测时间: {$data['detection_time']}n" .
"[点击查看详情]({$data['admin_order_url']})"
),
'at' => array(
'atMobiles' => get_option('dingtalk_at_mobiles', array()),
'isAtAll' => false
)
);
$response = wp_remote_post($webhook_url, array(
'headers' => array('Content-Type' => 'application/json'),
'body' => json_encode($message),
'timeout' => 5
));
return !is_wp_error($response);
}
}
/**
* 异常处理性能监控
*/
class Performance_Monitor {
private $start_time;
private $memory_usage;
public function __construct() {
$this->start_time = microtime(true);
$this->memory_usage = memory_get_usage();
}
/**
* 记录处理性能指标
*/
public function log_performance($operation, $order_count) {
$end_time = microtime(true);
$execution_time = $end_time - $this->start_time;
$memory_peak = memory_get_peak_usage() / 1024 / 1024; // 转换为MB
global $wpdb;
$table_name = $wpdb->prefix . 'abnormality_performance_logs';
$wpdb->insert($table_name, array(
'operation' => $operation,
'order_count' => $order_count,
'execution_time' => $execution_time,
'memory_peak_mb' => $memory_peak,
'log_time' => current_time('mysql')
));
// 如果执行时间过长,发送警告
if ($execution_time > 30) { // 超过30秒
$this->send_performance_alert($operation, $execution_time, $order_count);
}
}
/**
* 获取性能统计报告
*/
public function get_performance_report($days = 7) {
global $wpdb;
$table_name = $wpdb->prefix . 'abnormality_performance_logs';
$report = $wpdb->get_results($wpdb->prepare(
"SELECT
operation,
COUNT(*) as total_runs,
AVG(execution_time) as avg_time,
AVG(memory_peak_mb) as avg_memory,
MAX(execution_time) as max_time,
MIN(execution_time) as min_time,
DATE(log_time) as log_date
FROM {$table_name}
WHERE log_time >= DATE_SUB(NOW(), INTERVAL %d DAY)
GROUP BY operation, DATE(log_time)
ORDER BY log_date DESC, operation",
$days
));
return $report;
}
}
/**
* 异常处理性能监控
*/
class Performance_Monitor {
private $start_time;
private $memory_usage;
public function __construct() {
$this->start_time = microtime(true);
$this->memory_usage = memory_get_usage();
}
/**
* 记录处理性能指标
*/
public function log_performance($operation, $order_count) {
$end_time = microtime(true);
$execution_time = $end_time - $this->start_time;
$memory_peak = memory_get_peak_usage() / 1024 / 1024; // 转换为MB
global $wpdb;
$table_name = $wpdb->prefix . 'abnormality_performance_logs';
$wpdb->insert($table_name, array(
'operation' => $operation,
'order_count' => $order_count,
'execution_time' => $execution_time,
'memory_peak_mb' => $memory_peak,
'log_time' => current_time('mysql')
));
// 如果执行时间过长,发送警告
if ($execution_time > 30) { // 超过30秒
$this->send_performance_alert($operation, $execution_time, $order_count);
}
}
/**
* 获取性能统计报告
*/
public function get_performance_report($days = 7) {
global $wpdb;
$table_name = $wpdb->prefix . 'abnormality_performance_logs';
$report = $wpdb->get_results($wpdb->prepare(
"SELECT
operation,
COUNT(*) as total_runs,
AVG(execution_time) as avg_time,
AVG(memory_peak_mb) as avg_memory,
MAX(execution_time) as max_time,
MIN(execution_time) as min_time,
DATE(log_time) as log_date
FROM {$table_name}
WHERE log_time >= DATE_SUB(NOW(), INTERVAL %d DAY)
GROUP BY operation, DATE(log_time)
ORDER BY log_date DESC, operation",
$days
));
return $report;
}
}
/**
* 批量异常订单处理器
* 优化大量订单处理性能
*/
class Batch_Order_Processor {
/**
* 分批处理异常订单
*/
public function process_orders_in_batches($order_ids, $batch_size = 50) {
$total_orders = count($order_ids);
$batches = array_chunk($order_ids, $batch_size);
$results = array(
'processed' => 0,
'abnormalities_found' => 0,
'errors' => 0
);
$monitor = new Performance_Monitor();
foreach ($batches as $batch_index => $batch) {
// 每批处理前检查执行时间
if ($this->is_time_limit_approaching()) {
$this->log_interrupted_batch($batch_index, $batch_size);
break;
}
foreach ($batch as $order_id) {
try {
$abnormalities = $this->detect_order_abnormalities($order_id);
if (!empty($abnormalities)) {
$processor = new Abnormal_Order_Processor();
$processor->process_abnormal_order($order_id, $abnormalities);
$results['abnormalities_found']++;
}
$results['processed']++;
// 每处理10个订单休息一下,避免服务器过载
if ($results['processed'] % 10 === 0) {
usleep(100000); // 0.1秒
}
} catch (Exception $e) {
error_log("处理订单 {$order_id} 时出错: " . $e->getMessage());
$results['errors']++;
}
}
// 记录每批处理进度
$this->update_batch_progress($batch_index + 1, count($batches));
}
$monitor->log_performance('batch_processing', $total_orders);
return $results;
}
/**
* 检查是否接近执行时间限制
*/
private function is_time_limit_approaching() {
$max_execution_time = ini_get('max_execution_time');
if ($max_execution_time <= 0) {
$max_execution_time = 30; // 默认30秒
}
$elapsed_time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
$time_remaining = $max_execution_time - $elapsed_time;
// 如果剩余时间少于5秒,停止处理新批次
return $time_remaining < 5;
}
}
/**
* 批量异常订单处理器
* 优化大量订单处理性能
*/
class Batch_Order_Processor {
/**
* 分批处理异常订单
*/
public function process_orders_in_batches($order_ids, $batch_size = 50) {
$total_orders = count($order_ids);
$batches = array_chunk($order_ids, $batch_size);
$results = array(
'processed' => 0,
'abnormalities_found' => 0,
'errors' => 0
);
$monitor = new Performance_Monitor();
foreach ($batches as $batch_index => $batch) {
// 每批处理前检查执行时间
if ($this->is_time_limit_approaching()) {
$this->log_interrupted_batch($batch_index, $batch_size);
break;
}
foreach ($batch as $order_id) {
try {
$abnormalities = $this->detect_order_abnormalities($order_id);
if (!empty($abnormalities)) {
$processor = new Abnormal_Order_Processor();
$processor->process_abnormal_order($order_id, $abnormalities);
$results['abnormalities_found']++;
}
$results['processed']++;
// 每处理10个订单休息一下,避免服务器过载
if ($results['processed'] % 10 === 0) {
usleep(100000); // 0.1秒
}
} catch (Exception $e) {
error_log("处理订单 {$order_id} 时出错: " . $e->getMessage());
$results['errors']++;
}
}
// 记录每批处理进度
$this->update_batch_progress($batch_index + 1, count($batches));
}
$monitor->log_performance('batch_processing', $total_orders);
return $results;
}
/**
* 检查是否接近执行时间限制
*/
private function is_time_limit_approaching() {
$max_execution_time = ini_get('max_execution_time');
if ($max_execution_time <= 0) {
$max_execution_time = 30; // 默认30秒
}
$elapsed_time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
$time_remaining = $max_execution_time - $elapsed_time;
// 如果剩余时间少于5秒,停止处理新批次
return $time_remaining < 5;
}
}
/**
* 异常订单处理单元测试
*/
class Abnormal_Order_Test extends WP_UnitTestCase {
/**
* 测试支付超时检测
*/
public function test_payment_timeout_detection() {
// 创建测试订单
$order = WC_Helper_Order::create_order();
$order->set_status('pending');
$order->set_date_created(strtotime('-35 minutes')); // 超过30分钟
$order->save();
// 检测异常
$abnormalities = detect_payment_abnormalities($order->get_id());
// 验证结果
$this->assertNotEmpty($abnormalities);
$this->assertEquals('payment_timeout', $abnormalities[0]['type']);
}
/**
* 测试库存不足检测
*/
public function test_insufficient_stock_detection() {
// 创建低库存产品
$product = WC_Helper_Product::create_simple_product();
$product->set_stock_quantity(2);
$product->save();
// 创建订单,数量为3
$order = WC_Helper_Order::create_order();
$order->add_product($product, 3);
$order->save();
// 检测异常
$abnormalities = detect_inventory_abnormalities($order->get_id());
// 验证结果
$this->assertNotEmpty($abnormalities);
$this->assertEquals('insufficient_stock', $abnormalities[0]['type']);
$this->assertEquals(2, $abnormalities[0]['available']);
$this->assertEquals(3, $abnormalities[0]['required']);
}
/**
* 测试订单拆分功能
*/
public function test_order_splitting() {
// 创建有库存和缺货产品
$in_stock_product = WC_Helper_Product::create_simple_product();
$in_stock_product->set_stock_quantity(10);
$in_stock_product->save();
$out_of_stock_product = WC_Helper_Product::create_simple_product();
$out_of_stock_product->set_stock_quantity(0);
$out_of_stock_product->save();
// 创建包含两种产品的订单
$order = WC_Helper_Order::create_order();
$order->add_product($in_stock_product, 2);
$order->add_product($out_of_stock_product, 1);
$order->save();
// 执行拆分
$processor = new Abnormal_Order_Processor();
$abnormalities = array(array('type' => 'insufficient_stock'));
$processor->process_abnormal_order($order->get_id(), $abnormalities);
// 验证原订单只包含有库存产品
$order = wc_get_order($order->get_id());
$items = $order->get_items();
$this->assertCount(1, $items);
// 验证新订单已创建
$new_orders = wc_get_orders(array(
'created_via' => 'abnormal_order_split',
'limit' => 1
));
$this->assertNotEmpty($new_orders);
}
}
/**
* 异常订单处理单元测试
*/
class Abnormal_Order_Test extends WP_UnitTestCase {
/**
* 测试支付超时检测
*/
public function test_payment_timeout_detection() {
// 创建测试订单
$order = WC_Helper_Order::create_order();
$order->set_status('pending');
$order->set_date_created(strtotime('-35 minutes')); // 超过30分钟
$order->save();
// 检测异常
$abnormalities = detect_payment_abnormalities($order->get_id());
// 验证结果
$this->assertNotEmpty($abnormalities);
$this->assertEquals('payment_timeout', $abnormalities[0]['type']);
}
/**
* 测试库存不足检测
*/
public function test_insufficient_stock_detection() {
// 创建低库存产品
$product = WC_Helper_Product::create_simple_product();
$product->set_stock_quantity(2);
$product->save();
// 创建订单,数量为3
$order = WC_Helper_Order::create_order();
$order->add_product($product, 3);
$order->save();
// 检测异常
$abnormalities = detect_inventory_abnormalities($order->get_id());
// 验证结果
$this->assertNotEmpty($abnormalities);
$this->assertEquals('insufficient_stock', $abnormalities[0]['type']);
$this->assertEquals(2, $abnormalities[0]['available']);
$this->assertEquals(3, $abnormalities[0]['required']);
}
/**
* 测试订单拆分功能
*/
public function test_order_splitting() {
// 创建有库存和缺货产品
$in_stock_product = WC_Helper_Product::create_simple_product();
$in_stock_product->set_stock_quantity(10);
$in_stock_product->save();
$out_of_stock_product = WC_Helper_Product::create_simple_product();
$out_of_stock_product->set_stock_quantity(0);
$out_of_stock_product->save();
// 创建包含两种产品的订单
$order = WC_Helper_Order::create_order();
$order->add_product($in_stock_product, 2);
$order->add_product($out_of_stock_product, 1);
$order->save();
// 执行拆分
$processor = new Abnormal_Order_Processor();
$abnormalities = array(array('type' => 'insufficient_stock'));
$processor->process_abnormal_order($order->get_id(), $abnormalities);
// 验证原订单只包含有库存产品
$order = wc_get_order($order->get_id());
$items = $order->get_items();
$this->assertCount(1, $items);
// 验证新订单已创建
$new_orders = wc_get_orders(array(
'created_via' => 'abnormal_order_split',
'limit' => 1
));
$this->assertNotEmpty($new_orders);
}
}
/**
* 异常处理调试工具
*/
class Abnormal_Order_Debugger {
/**
* 显示详细的调试信息
*/
public static function debug_order($order_id) {
$order = wc_get_order($order_id);
if (!$order) {
return "订单不存在";
}
$debug_info = array(
'订单基本信息' => array(
'订单号' => $order->get_id(),
'订单状态' => $order->get_status(),
'订单金额' => $order->get_total(),
'支付方式' => $order->get_payment_method(),
'创建时间' => $order->get_date_created()->format('Y-m-d H:i:s'),
'客户ID' => $order->get_customer_id()
),
'异常检测结果' => array(),
'处理历史' => array()
);
// 运行所有异常检测
$debug_info['异常检测结果']['支付异常'] = detect_payment_abnormalities($order_id);
$debug_info['异常检测结果']['库存异常'] = detect_inventory_abnormalities($order_id);
// 获取处理历史
global $wpdb;
$logs = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}abnormal_order_logs
WHERE order_id = %d
ORDER BY detection_time DESC",
$order_id
));
foreach ($logs as $log) {
$debug_info['处理历史'][] = array(
'异常类型' => $log->abnormal_type,
'检测时间' => $log->detection_time,
'处理动作' => $log->action_taken,
'处理时间' => $log->action_time,
'处理状态' => $log->resolved ? '已解决' : '待处理',
'备注' => $log->notes
);
}
// 输出调试信息
echo '<pre>';
print_r($debug_info);
echo '</pre>';
// 记录调试日志
self::log_debug_info($order_id, $debug_info);
return $debug_info;
}
/**
* 模拟异常场景
*/
public static function simulate_abnormal_scenario($scenario_type) {
switch ($scenario_type) {
case 'payment_timeout':
/**
* 异常处理调试工具
*/
class Abnormal_Order_Debugger {
/**
* 显示详细的调试信息
*/
public static function debug_order($order_id) {
$order = wc_get_order($order_id);
if (!$order) {
return "订单不存在";
}
$debug_info = array(
'订单基本信息' => array(
'订单号' => $order->get_id(),
'订单状态' => $order->get_status(),
'订单金额' => $order->get_total(),
'支付方式' => $order->get_payment_method(),
'创建时间' => $order->get_date_created()->format('Y-m-d H:i:s'),
'客户ID' => $order->get_customer_id()
),
'异常检测结果' => array(),
'处理历史' => array()
);
// 运行所有异常检测
$debug_info['异常检测结果']['支付异常'] = detect_payment_abnormalities($order_id);
$debug_info['异常检测结果']['库存异常'] = detect_inventory_abnormalities($order_id);
// 获取处理历史
global $wpdb;
$logs = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}abnormal_order_logs
WHERE order_id = %d
ORDER BY detection_time DESC",
$order_id
));
foreach ($logs as $log) {
$debug_info['处理历史'][] = array(
'异常类型' => $log->abnormal_type,
'检测时间' => $log->detection_time,
'处理动作' => $log->action_taken,
'处理时间' => $log->action_time,
'处理状态' => $log->resolved ? '已解决' : '待处理',
'备注' => $log->notes
);
}
// 输出调试信息
echo '<pre>';
print_r($debug_info);
echo '</pre>';
// 记录调试日志
self::log_debug_info($order_id, $debug_info);
return $debug_info;
}
/**
* 模拟异常场景
*/
public static function simulate_abnormal_scenario($scenario_type) {
switch ($scenario_type) {
case 'payment_timeout':


