文章目录
-
- 在电子商务日益普及的今天,即使是小型企业和个人卖家也需要高效管理订单。虽然市面上有许多成熟的电商平台,但许多WordPress用户希望在自己的网站上直接管理小批量订单,而不依赖第三方平台。本教程将指导您开发一个简单但功能完整的小批量订单管理WordPress插件,适合处理每日几十到几百个订单的场景。
- 在开始编码之前,我们先规划插件的基本功能: 订单创建与管理 - 添加、查看、编辑和删除订单 订单状态跟踪 - 待处理、处理中、已完成、已取消等状态 客户信息管理 - 记录客户基本信息 简单统计功能 - 显示订单数量、金额统计 数据导出 - 支持导出订单数据为CSV格式
- 确保您已准备好以下环境: WordPress 5.0+ 安装 PHP 7.2+ 环境 MySQL 5.6+ 数据库 代码编辑器(如VS Code、Sublime Text等)
- 在WordPress的wp-content/plugins目录下创建新文件夹mini-order-manager,并创建以下文件结构: mini-order-manager/ ├── mini-order-manager.php # 主插件文件 ├── includes/ │ ├── class-database.php # 数据库处理类 │ ├── class-orders.php # 订单管理类 │ └── class-admin-page.php # 后台管理页面 ├── assets/ │ ├── css/ │ │ └── admin-style.css # 后台样式 │ └── js/ │ └── admin-script.js # 后台脚本 └── templates/ # 模板文件(可选)
- mini-order-manager.php <?php /** * Plugin Name: 小批量订单管理器 * Plugin URI: https://yourwebsite.com/ * Description: 一个简单的小批量订单管理插件,适合小型电商使用 * Version: 1.0.0 * Author: 您的名字 * License: GPL v2 or later * Text Domain: mini-order-manager */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('MOM_PLUGIN_VERSION', '1.0.0'); define('MOM_PLUGIN_PATH', plugin_dir_path(__FILE__)); define('MOM_PLUGIN_URL', plugin_dir_url(__FILE__)); // 自动加载类文件 spl_autoload_register(function ($class_name) { if (strpos($class_name, 'MOM_') === 0) { $file = MOM_PLUGIN_PATH . 'includes/class-' . strtolower(str_replace('_', '-', $class_name)) . '.php'; if (file_exists($file)) { require_once $file; } } }); // 初始化插件 function mom_init_plugin() { // 实例化数据库类并创建表 $database = new MOM_Database(); $database->create_tables(); // 实例化管理页面类 if (is_admin()) { new MOM_Admin_Page(); } } add_action('plugins_loaded', 'mom_init_plugin'); // 激活插件时执行的操作 function mom_activate_plugin() { // 创建数据库表 $database = new MOM_Database(); $database->create_tables(); // 设置默认选项 add_option('mom_plugin_version', MOM_PLUGIN_VERSION); } register_activation_hook(__FILE__, 'mom_activate_plugin'); // 停用插件时执行的操作 function mom_deactivate_plugin() { // 清理临时数据 delete_option('mom_temp_data'); } register_deactivation_hook(__FILE__, 'mom_deactivate_plugin');
- includes/class-database.php <?php /** * 数据库处理类 * 负责创建和管理插件所需的数据库表 */ class MOM_Database { private $charset_collate; public function __construct() { global $wpdb; $this->charset_collate = $wpdb->get_charset_collate(); } /** * 创建插件所需的数据库表 */ public function create_tables() { global $wpdb; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); // 订单表 $table_name = $wpdb->prefix . 'mom_orders'; $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, order_number varchar(50) NOT NULL, customer_name varchar(100) NOT NULL, customer_email varchar(100), customer_phone varchar(20), order_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, total_amount decimal(10,2) NOT NULL DEFAULT 0.00, status varchar(20) DEFAULT 'pending', payment_method varchar(50), notes text, PRIMARY KEY (id), UNIQUE KEY order_number (order_number) ) {$this->charset_collate};"; dbDelta($sql); // 订单项目表 $table_name_items = $wpdb->prefix . 'mom_order_items'; $sql_items = "CREATE TABLE IF NOT EXISTS $table_name_items ( id mediumint(9) NOT NULL AUTO_INCREMENT, order_id mediumint(9) NOT NULL, product_name varchar(200) NOT NULL, quantity int NOT NULL DEFAULT 1, unit_price decimal(10,2) NOT NULL DEFAULT 0.00, total_price decimal(10,2) NOT NULL DEFAULT 0.00, PRIMARY KEY (id), FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}mom_orders(id) ON DELETE CASCADE ) {$this->charset_collate};"; dbDelta($sql_items); // 创建状态表(可选,用于存储状态选项) $table_name_status = $wpdb->prefix . 'mom_order_status'; $sql_status = "CREATE TABLE IF NOT EXISTS $table_name_status ( id mediumint(9) NOT NULL AUTO_INCREMENT, status_key varchar(50) NOT NULL, status_label varchar(100) NOT NULL, is_default tinyint(1) DEFAULT 0, PRIMARY KEY (id) ) {$this->charset_collate};"; dbDelta($sql_status); // 插入默认状态数据 $this->insert_default_statuses(); } /** * 插入默认订单状态 */ private function insert_default_statuses() { global $wpdb; $table_name = $wpdb->prefix . 'mom_order_status'; $default_statuses = array( array('pending', '待处理', 1), array('processing', '处理中', 0), array('completed', '已完成', 0), array('cancelled', '已取消', 0), array('refunded', '已退款', 0) ); foreach ($default_statuses as $status) { // 检查是否已存在 $exists = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE status_key = %s", $status[0] )); if (!$exists) { $wpdb->insert( $table_name, array( 'status_key' => $status[0], 'status_label' => $status[1], 'is_default' => $status[2] ), array('%s', '%s', '%d') ); } } } /** * 获取所有订单状态 */ public function get_order_statuses() { global $wpdb; $table_name = $wpdb->prefix . 'mom_order_status'; return $wpdb->get_results("SELECT * FROM $table_name ORDER BY id"); } }
- includes/class-orders.php <?php /** * 订单管理类 * 处理订单的CRUD操作 */ class MOM_Orders { private $db; public function __construct() { global $wpdb; $this->db = $wpdb; } /** * 创建新订单 * @param array $order_data 订单数据 * @return int|false 成功返回订单ID,失败返回false */ public function create_order($order_data) { $table_name = $this->db->prefix . 'mom_orders'; // 生成订单号 if (empty($order_data['order_number'])) { $order_data['order_number'] = $this->generate_order_number(); } // 设置默认值 $defaults = array( 'order_date' => current_time('mysql'), 'status' => 'pending', 'total_amount' => 0.00 ); $order_data = wp_parse_args($order_data, $defaults); // 插入订单数据 $result = $this->db->insert( $table_name, $order_data, array( '%s', // order_number '%s', // customer_name '%s', // customer_email '%s', // customer_phone '%s', // order_date '%f', // total_amount '%s', // status '%s', // payment_method '%s' // notes ) ); if ($result) { return $this->db->insert_id; } return false; } /** * 生成唯一订单号 * @return string 订单号 */ private function generate_order_number() { $prefix = 'ORD'; $date = date('Ymd'); $random = mt_rand(1000, 9999); return $prefix . $date . $random; } /** * 获取订单列表 * @param array $args 查询参数 * @return array 订单列表 */ public function get_orders($args = array()) { $table_name = $this->db->prefix . 'mom_orders'; $defaults = array( 'per_page' => 20, 'page' => 1, 'status' => '', 'search' => '', 'orderby' => 'order_date', 'order' => 'DESC' ); $args = wp_parse_args($args, $defaults); $where = ' WHERE 1=1'; $params = array(); // 按状态筛选 if (!empty($args['status'])) { $where .= " AND status = %s"; $params[] = $args['status']; } // 搜索功能 if (!empty($args['search'])) { $where .= " AND (customer_name LIKE %s OR order_number LIKE %s OR customer_email LIKE %s)"; $search_term = '%' . $this->db->esc_like($args['search']) . '%'; $params[] = $search_term; $params[] = $search_term; $params[] = $search_term; } // 计算偏移量 $offset = ($args['page'] - 1) * $args['per_page']; // 构建查询 $query = "SELECT * FROM $table_name $where"; // 添加参数 if (!empty($params)) { $query = $this->db->prepare($query, $params); } // 添加排序 $query .= " ORDER BY {$args['orderby']} {$args['order']}"; // 添加分页 $query .= " LIMIT {$args['per_page']} OFFSET $offset"; return $this->db->get_results($query); } /** * 获取单个订单详情 * @param int $order_id 订单ID * @return object|null 订单对象或null */ public function get_order($order_id) { $table_name = $this->db->prefix . 'mom_orders'; return $this->db->get_row($this->db->prepare( "SELECT * FROM $table_name WHERE id = %d", $order_id )); } /** * 更新订单 * @param int $order_id 订单ID * @param array $data 更新数据 * @return bool 是否成功 */ public function update_order($order_id, $data) { $table_name = $this->db->prefix . 'mom_orders'; return $this->db->update( $table_name, $data, array('id' => $order_id), array('%s', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s'), array('%d') ); } /** * 删除订单 * @param int $order_id 订单ID * @return bool 是否成功 */ public function delete_order($order_id) { $table_name = $this->db->prefix . 'mom_orders'; return $this->db->delete( $table_name, array('id' => $order_id), array('%d') ); } /** * 获取订单统计 * @return array 统计信息 */ public function get_order_stats() { $table_name = $this->db->prefix . 'mom_orders'; $stats = array(); // 总订单数 $stats['total_orders'] = $this->db->get_var("SELECT COUNT(*) FROM $table_name"); // 总金额 $stats['total_revenue'] = $this->db->get_var("SELECT SUM(total_amount) FROM $table_name WHERE status NOT IN ('cancelled', 'refunded')"); // 按状态统计 $status_counts = $this->db->get_results("SELECT status, COUNT(*) as count FROM $table_name GROUP BY status"); foreach ($status_counts as $status) { $stats['status_counts'][$status->status] = $status->count; } return $stats; } }
- includes/class-admin-page.php <?php /** * 后台管理页面类 * 处理插件在WordPress后台的显示和功能 */ class MOM_Admin_Page { public function __construct() { // 添加管理菜单 add_action('admin_menu', array($this, 'add_admin_menu')); // 加载脚本和样式 add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets')); } /** * 添加管理菜单 */ public function add_admin_menu() { // 主菜单 add_menu_page( '订单管理', // 页面标题 '订单管理', // 菜单标题 'manage_options', // 权限 'mom-orders', // 菜单slug array($this, 'display_orders_page'), // 回调函数 'dashicons-cart', // 图标 30 // 位置 ); // 子菜单:所有订单 add_submenu_page( 'mom-orders', '所有订单', '所有订单', 'manage_options', 'mom-orders', array($this, 'display_orders_page') ); // 子菜单:添加新订单 add_submenu_page( 'mom-orders', '添加新订单', '添加新订单', 'manage_options', 'mom-add-order', array($this, 'display_add_order_page') ); // 子菜单:统计 add_submenu_page( 'mom-orders', '订单统计', '统计', 'manage_options', 'mom-statistics', array($this, 'display_statistics_page') ); } /** * 加载后台资源 */ public function enqueue_admin_assets($hook) { // 只在插件页面加载 if (strpos($hook, 'mom-') === false) { return; } // 加载CSS wp_enqueue_style( 'mom-admin-style', MOM_PLUGIN_URL . 'assets/css/admin-style.css', array(), MOM_PLUGIN_VERSION ); // 加载JS wp_enqueue_script( 'mom-admin-script', MOM_PLUGIN_URL . 'assets/js/admin-script.js', array('jquery'), MOM_PLUGIN_VERSION, true ); // 本地化脚本,传递数据到JS wp_localize_script('mom-admin-script', 'mom_ajax', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('mom_ajax_nonce') )); } /** * 显示订单列表页面 */ public function display_orders_page() { // 实例化订单类 $orders_manager = new MOM_Orders(); // 获取当前页和状态筛选 $current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1; $status_filter = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : ''; $search_term = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : ''; // 获取订单数据 $args = array( 'per_page' => 20, 'page' => $current_page, 'status' => $status_filter, search_term ); $orders = $orders_manager->get_orders($args); $total_orders = $orders_manager->get_order_stats()['total_orders']; $total_pages = ceil($total_orders / $args['per_page']); // 获取所有状态 $database = new MOM_Database(); $statuses = $database->get_order_statuses(); ?> <div class="wrap mom-admin-wrap"> <h1 class="wp-heading-inline">订单管理</h1> <a href="<?php echo admin_url('admin.php?page=mom-add-order'); ?>" class="page-title-action">添加新订单</a> <!-- 搜索和筛选表单 --> <div class="mom-filters"> <form method="get" action="<?php echo admin_url('admin.php'); ?>"> <input type="hidden" name="page" value="mom-orders"> <div class="search-box"> <input type="search" name="s" value="<?php echo esc_attr($search_term); ?>" placeholder="搜索订单号、客户姓名或邮箱"> <input type="submit" class="button" value="搜索"> </div> <div class="status-filter"> <select name="status" onchange="this.form.submit()"> <option value="">所有状态</option> <?php foreach ($statuses as $status): ?> <option value="<?php echo esc_attr($status->status_key); ?>" <?php selected($status_filter, $status->status_key); ?>> <?php echo esc_html($status->status_label); ?> </option> <?php endforeach; ?> </select> </div> </form> </div> <!-- 订单列表表格 --> <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 if (empty($orders)): ?> <tr> <td colspan="6" style="text-align: center;">暂无订单</td> </tr> <?php else: ?> <?php foreach ($orders as $order): ?> <tr> <td><?php echo esc_html($order->order_number); ?></td> <td><?php echo esc_html($order->customer_name); ?></td> <td><?php echo date('Y-m-d H:i', strtotime($order->order_date)); ?></td> <td><?php echo number_format($order->total_amount, 2); ?>元</td> <td> <span class="order-status status-<?php echo esc_attr($order->status); ?>"> <?php $status_label = ''; foreach ($statuses as $status) { if ($status->status_key == $order->status) { $status_label = $status->status_label; break; } } echo esc_html($status_label); ?> </span> </td> <td> <a href="<?php echo admin_url('admin.php?page=mom-add-order&order_id=' . $order->id); ?>" class="button button-small">编辑</a> <a href="#" class="button button-small button-delete" data-order-id="<?php echo $order->id; ?>">删除</a> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> <!-- 分页 --> <?php if ($total_pages > 1): ?> <div class="tablenav bottom"> <div class="tablenav-pages"> <span class="displaying-num">共 <?php echo $total_orders; ?> 个订单</span> <span class="pagination-links"> <?php $base_url = admin_url('admin.php?page=mom-orders'); if ($status_filter) $base_url .= '&status=' . $status_filter; if ($search_term) $base_url .= '&s=' . urlencode($search_term); if ($current_page > 1) { echo '<a class="first-page button" href="' . $base_url . '&paged=1">«</a>'; echo '<a class="prev-page button" href="' . $base_url . '&paged=' . ($current_page - 1) . '">‹</a>'; } echo '<span class="paging-input">'; echo '<input class="current-page" type="text" size="2" value="' . $current_page . '" name="paged">'; echo ' 页,共 <span class="total-pages">' . $total_pages . '</span> 页'; echo '</span>'; if ($current_page < $total_pages) { echo '<a class="next-page button" href="' . $base_url . '&paged=' . ($current_page + 1) . '">›</a>'; echo '<a class="last-page button" href="' . $base_url . '&paged=' . $total_pages . '">»</a>'; } ?> </span> </div> </div> <?php endif; ?> </div> <?php } /** * 显示添加/编辑订单页面 */ public function display_add_order_page() { $orders_manager = new MOM_Orders(); $database = new MOM_Database(); $statuses = $database->get_order_statuses(); $order_id = isset($_GET['order_id']) ? intval($_GET['order_id']) : 0; $order = $order_id ? $orders_manager->get_order($order_id) : null; // 处理表单提交 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mom_save_order'])) { $this->save_order($order_id); $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; $order = $order_id ? $orders_manager->get_order($order_id) : null; } ?> <div class="wrap"> <h1><?php echo $order ? '编辑订单' : '添加新订单'; ?></h1> <form method="post" action=""> <?php wp_nonce_field('mom_save_order', 'mom_order_nonce'); ?> <input type="hidden" name="order_id" value="<?php echo $order ? $order->id : 0; ?>"> <div class="mom-form-container"> <div class="mom-form-section"> <h2>订单信息</h2> <table class="form-table"> <tr> <th><label for="order_number">订单号</label></th> <td> <input type="text" id="order_number" name="order_number" value="<?php echo $order ? esc_attr($order->order_number) : ''; ?>" class="regular-text" required> <p class="description">系统将自动生成订单号,如需自定义可修改</p> </td> </tr> <tr> <th><label for="order_date">订单日期</label></th> <td> <input type="datetime-local" id="order_date" name="order_date" value="<?php echo $order ? date('Y-m-dTH:i', strtotime($order->order_date)) : date('Y-m-dTH:i'); ?>" class="regular-text" required> </td> </tr> <tr> <th><label for="status">订单状态</label></th> <td> <select id="status" name="status" class="regular-text"> <?php foreach ($statuses as $status): ?> <option value="<?php echo esc_attr($status->status_key); ?>" <?php echo ($order && $order->status == $status->status_key) ? 'selected' : ''; ?>> <?php echo esc_html($status->status_label); ?> </option> <?php endforeach; ?> </select> </td> </tr> </table> </div> <div class="mom-form-section"> <h2>客户信息</h2> <table class="form-table"> <tr> <th><label for="customer_name">客户姓名</label></th> <td> <input type="text" id="customer_name" name="customer_name" value="<?php echo $order ? esc_attr($order->customer_name) : ''; ?>" class="regular-text" required> </td> </tr> <tr> <th><label for="customer_email">客户邮箱</label></th> <td> <input type="email" id="customer_email" name="customer_email" value="<?php echo $order ? esc_attr($order->customer_email) : ''; ?>" class="regular-text"> </td> </tr> <tr> <th><label for="customer_phone">客户电话</label></th> <td> <input type="tel" id="customer_phone" name="customer_phone" value="<?php echo $order ? esc_attr($order->customer_phone) : ''; ?>" class="regular-text"> </td> </tr> </table> </div> <div class="mom-form-section"> <h2>订单详情</h2> <table class="form-table"> <tr> <th><label for="total_amount">订单总额</label></th> <td> <input type="number" id="total_amount" name="total_amount" value="<?php echo $order ? esc_attr($order->total_amount) : '0.00'; ?>" step="0.01" min="0" class="small-text" required> 元 </td> </tr> <tr> <th><label for="payment_method">支付方式</label></th> <td> <select id="payment_method" name="payment_method" class="regular-text"> <option value="">请选择支付方式</option> <option value="alipay" <?php echo ($order && $order->payment_method == 'alipay') ? 'selected' : ''; ?>>支付宝</option> <option value="wechat" <?php echo ($order && $order->payment_method == 'wechat') ? 'selected' : ''; ?>>微信支付</option> <option value="bank" <?php echo ($order && $order->payment_method == 'bank') ? 'selected' : ''; ?>>银行转账</option> <option value="cash" <?php echo ($order && $order->payment_method == 'cash') ? 'selected' : ''; ?>>现金</option> </select> </td> </tr> <tr> <th><label for="notes">备注</label></th> <td> <textarea id="notes" name="notes" rows="4" class="large-text"><?php echo $order ? esc_textarea($order->notes) : ''; ?></textarea> </td> </tr> </table> </div> <div class="submit"> <input type="submit" name="mom_save_order" class="button button-primary" value="保存订单"> <a href="<?php echo admin_url('admin.php?page=mom-orders'); ?>" class="button">返回订单列表</a> </div> </div> </form> </div> <?php } /** * 保存订单 */ private function save_order($order_id) { // 验证nonce if (!isset($_POST['mom_order_nonce']) || !wp_verify_nonce($_POST['mom_order_nonce'], 'mom_save_order')) { wp_die('安全验证失败'); } // 验证权限 if (!current_user_can('manage_options')) { wp_die('权限不足'); } // 准备订单数据 $order_data = array( 'order_number' => sanitize_text_field($_POST['order_number']), 'customer_name' => sanitize_text_field($_POST['customer_name']), 'customer_email' => sanitize_email($_POST['customer_email']), 'customer_phone' => sanitize_text_field($_POST['customer_phone']), 'order_date' => sanitize_text_field($_POST['order_date']), 'total_amount' => floatval($_POST['total_amount']), 'status' => sanitize_text_field($_POST['status']), 'payment_method' => sanitize_text_field($_POST['payment_method']), 'notes' => sanitize_textarea_field($_POST['notes']) ); $orders_manager = new MOM_Orders(); if ($order_id) { // 更新订单 $result = $orders_manager->update_order($order_id, $order_data); if ($result) { add_action('admin_notices', function() { echo '<div class="notice notice-success is-dismissible"><p>订单更新成功!</p></div>'; }); } } else { // 创建新订单 $new_order_id = $orders_manager->create_order($order_data); if ($new_order_id) { add_action('admin_notices', function() { echo '<div class="notice notice-success is-dismissible"><p>订单创建成功!</p></div>'; }); } } } /** * 显示统计页面 */ public function display_statistics_page() { $orders_manager = new MOM_Orders(); $stats = $orders_manager->get_order_stats(); // 获取最近30天的订单数据 global $wpdb; $table_name = $wpdb->prefix . 'mom_orders'; $thirty_days_ago = date('Y-m-d', strtotime('-30 days')); $daily_stats = $wpdb->get_results($wpdb->prepare( "SELECT DATE(order_date) as date, COUNT(*) as count, SUM(total_amount) as revenue FROM $table_name WHERE order_date >= %s GROUP BY DATE(order_date) ORDER BY date DESC", $thirty_days_ago )); ?> <div class="wrap"> <h1>订单统计</h1> <div class="mom-stats-container"> <div class="mom-stats-overview"> <div class="stat-box"> <h3>总订单数</h3> <div class="stat-number"><?php echo esc_html($stats['total_orders']); ?></div> </div> <div class="stat-box"> <h3>总销售额</h3> <div class="stat-number"><?php echo number_format($stats['total_revenue'], 2); ?>元</div> </div> <div class="stat-box"> <h3>平均订单额</h3> <div class="stat-number"> <?php $avg = $stats['total_orders'] > 0 ? $stats['total_revenue'] / $stats['total_orders'] : 0; echo number_format($avg, 2); ?>元 </div> </div> </div> <div class="mom-stats-details"> <h2>订单状态分布</h2> <table class="wp-list-table widefat fixed"> <thead> <tr> <th>状态</th> <th>订单数</th> <th>占比</th> </tr> </thead> <tbody> <?php $total_orders = $stats['total_orders']; if (isset($stats['status_counts'])) { foreach ($stats['status_counts'] as $status => $count) { $percentage = $total_orders > 0 ? ($count / $total_orders * 100) : 0; ?> <tr> <td><?php echo esc_html($status); ?></td> <td><?php echo esc_html($count); ?></td> <td><?php echo number_format($percentage, 1); ?>%</td> </tr> <?php } } ?> </tbody> </table> </div> <div class="mom-stats-chart"> <h2>最近30天订单趋势</h2> <table class="wp-list-table widefat fixed"> <thead> <tr> <th>日期</th> <th>订单数</th> <th>销售额</th> </tr> </thead> <tbody> <?php if (empty($daily_stats)): ?> <tr> <td colspan="3" style="text-align: center;">暂无数据</td> </tr> <?php else: ?> <?php foreach ($daily_stats as $daily): ?> <tr> <td><?php echo esc_html($daily->date); ?></td> <td><?php echo esc_html($daily->count); ?></td> <td><?php echo number_format($daily->revenue, 2); ?>元</td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> <div class="mom-export-section"> <h2>数据导出</h2> <p>导出订单数据为CSV格式:</p> <form method="post" action="<?php echo admin_url('admin-post.php'); ?>"> <input type="hidden" name="action" value="mom_export_orders"> <?php wp_nonce_field('mom_export_nonce'); ?> <label
在电子商务日益普及的今天,即使是小型企业和个人卖家也需要高效管理订单。虽然市面上有许多成熟的电商平台,但许多WordPress用户希望在自己的网站上直接管理小批量订单,而不依赖第三方平台。本教程将指导您开发一个简单但功能完整的小批量订单管理WordPress插件,适合处理每日几十到几百个订单的场景。
在开始编码之前,我们先规划插件的基本功能:
- 订单创建与管理 - 添加、查看、编辑和删除订单
- 订单状态跟踪 - 待处理、处理中、已完成、已取消等状态
- 客户信息管理 - 记录客户基本信息
- 简单统计功能 - 显示订单数量、金额统计
- 数据导出 - 支持导出订单数据为CSV格式
确保您已准备好以下环境:
- WordPress 5.0+ 安装
- PHP 7.2+ 环境
- MySQL 5.6+ 数据库
- 代码编辑器(如VS Code、Sublime Text等)
在WordPress的wp-content/plugins目录下创建新文件夹mini-order-manager,并创建以下文件结构:
mini-order-manager/
├── mini-order-manager.php # 主插件文件
├── includes/
│ ├── class-database.php # 数据库处理类
│ ├── class-orders.php # 订单管理类
│ └── class-admin-page.php # 后台管理页面
├── assets/
│ ├── css/
│ │ └── admin-style.css # 后台样式
│ └── js/
│ └── admin-script.js # 后台脚本
└── templates/ # 模板文件(可选)
mini-order-manager.php
<?php
/**
* Plugin Name: 小批量订单管理器
* Plugin URI: https://yourwebsite.com/
* Description: 一个简单的小批量订单管理插件,适合小型电商使用
* Version: 1.0.0
* Author: 您的名字
* License: GPL v2 or later
* Text Domain: mini-order-manager
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('MOM_PLUGIN_VERSION', '1.0.0');
define('MOM_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('MOM_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类文件
spl_autoload_register(function ($class_name) {
if (strpos($class_name, 'MOM_') === 0) {
$file = MOM_PLUGIN_PATH . 'includes/class-' . strtolower(str_replace('_', '-', $class_name)) . '.php';
if (file_exists($file)) {
require_once $file;
}
}
});
// 初始化插件
function mom_init_plugin() {
// 实例化数据库类并创建表
$database = new MOM_Database();
$database->create_tables();
// 实例化管理页面类
if (is_admin()) {
new MOM_Admin_Page();
}
}
add_action('plugins_loaded', 'mom_init_plugin');
// 激活插件时执行的操作
function mom_activate_plugin() {
// 创建数据库表
$database = new MOM_Database();
$database->create_tables();
// 设置默认选项
add_option('mom_plugin_version', MOM_PLUGIN_VERSION);
}
register_activation_hook(__FILE__, 'mom_activate_plugin');
// 停用插件时执行的操作
function mom_deactivate_plugin() {
// 清理临时数据
delete_option('mom_temp_data');
}
register_deactivation_hook(__FILE__, 'mom_deactivate_plugin');
includes/class-database.php
<?php
/**
* 数据库处理类
* 负责创建和管理插件所需的数据库表
*/
class MOM_Database {
private $charset_collate;
public function __construct() {
global $wpdb;
$this->charset_collate = $wpdb->get_charset_collate();
}
/**
* 创建插件所需的数据库表
*/
public function create_tables() {
global $wpdb;
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
// 订单表
$table_name = $wpdb->prefix . 'mom_orders';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
order_number varchar(50) NOT NULL,
customer_name varchar(100) NOT NULL,
customer_email varchar(100),
customer_phone varchar(20),
order_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
total_amount decimal(10,2) NOT NULL DEFAULT 0.00,
status varchar(20) DEFAULT 'pending',
payment_method varchar(50),
notes text,
PRIMARY KEY (id),
UNIQUE KEY order_number (order_number)
) {$this->charset_collate};";
dbDelta($sql);
// 订单项目表
$table_name_items = $wpdb->prefix . 'mom_order_items';
$sql_items = "CREATE TABLE IF NOT EXISTS $table_name_items (
id mediumint(9) NOT NULL AUTO_INCREMENT,
order_id mediumint(9) NOT NULL,
product_name varchar(200) NOT NULL,
quantity int NOT NULL DEFAULT 1,
unit_price decimal(10,2) NOT NULL DEFAULT 0.00,
total_price decimal(10,2) NOT NULL DEFAULT 0.00,
PRIMARY KEY (id),
FOREIGN KEY (order_id) REFERENCES {$wpdb->prefix}mom_orders(id) ON DELETE CASCADE
) {$this->charset_collate};";
dbDelta($sql_items);
// 创建状态表(可选,用于存储状态选项)
$table_name_status = $wpdb->prefix . 'mom_order_status';
$sql_status = "CREATE TABLE IF NOT EXISTS $table_name_status (
id mediumint(9) NOT NULL AUTO_INCREMENT,
status_key varchar(50) NOT NULL,
status_label varchar(100) NOT NULL,
is_default tinyint(1) DEFAULT 0,
PRIMARY KEY (id)
) {$this->charset_collate};";
dbDelta($sql_status);
// 插入默认状态数据
$this->insert_default_statuses();
}
/**
* 插入默认订单状态
*/
private function insert_default_statuses() {
global $wpdb;
$table_name = $wpdb->prefix . 'mom_order_status';
$default_statuses = array(
array('pending', '待处理', 1),
array('processing', '处理中', 0),
array('completed', '已完成', 0),
array('cancelled', '已取消', 0),
array('refunded', '已退款', 0)
);
foreach ($default_statuses as $status) {
// 检查是否已存在
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name WHERE status_key = %s",
$status[0]
));
if (!$exists) {
$wpdb->insert(
$table_name,
array(
'status_key' => $status[0],
'status_label' => $status[1],
'is_default' => $status[2]
),
array('%s', '%s', '%d')
);
}
}
}
/**
* 获取所有订单状态
*/
public function get_order_statuses() {
global $wpdb;
$table_name = $wpdb->prefix . 'mom_order_status';
return $wpdb->get_results("SELECT * FROM $table_name ORDER BY id");
}
}
includes/class-orders.php
<?php
/**
* 订单管理类
* 处理订单的CRUD操作
*/
class MOM_Orders {
private $db;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
}
/**
* 创建新订单
* @param array $order_data 订单数据
* @return int|false 成功返回订单ID,失败返回false
*/
public function create_order($order_data) {
$table_name = $this->db->prefix . 'mom_orders';
// 生成订单号
if (empty($order_data['order_number'])) {
$order_data['order_number'] = $this->generate_order_number();
}
// 设置默认值
$defaults = array(
'order_date' => current_time('mysql'),
'status' => 'pending',
'total_amount' => 0.00
);
$order_data = wp_parse_args($order_data, $defaults);
// 插入订单数据
$result = $this->db->insert(
$table_name,
$order_data,
array(
'%s', // order_number
'%s', // customer_name
'%s', // customer_email
'%s', // customer_phone
'%s', // order_date
'%f', // total_amount
'%s', // status
'%s', // payment_method
'%s' // notes
)
);
if ($result) {
return $this->db->insert_id;
}
return false;
}
/**
* 生成唯一订单号
* @return string 订单号
*/
private function generate_order_number() {
$prefix = 'ORD';
$date = date('Ymd');
$random = mt_rand(1000, 9999);
return $prefix . $date . $random;
}
/**
* 获取订单列表
* @param array $args 查询参数
* @return array 订单列表
*/
public function get_orders($args = array()) {
$table_name = $this->db->prefix . 'mom_orders';
$defaults = array(
'per_page' => 20,
'page' => 1,
'status' => '',
'search' => '',
'orderby' => 'order_date',
'order' => 'DESC'
);
$args = wp_parse_args($args, $defaults);
$where = ' WHERE 1=1';
$params = array();
// 按状态筛选
if (!empty($args['status'])) {
$where .= " AND status = %s";
$params[] = $args['status'];
}
// 搜索功能
if (!empty($args['search'])) {
$where .= " AND (customer_name LIKE %s OR order_number LIKE %s OR customer_email LIKE %s)";
$search_term = '%' . $this->db->esc_like($args['search']) . '%';
$params[] = $search_term;
$params[] = $search_term;
$params[] = $search_term;
}
// 计算偏移量
$offset = ($args['page'] - 1) * $args['per_page'];
// 构建查询
$query = "SELECT * FROM $table_name $where";
// 添加参数
if (!empty($params)) {
$query = $this->db->prepare($query, $params);
}
// 添加排序
$query .= " ORDER BY {$args['orderby']} {$args['order']}";
// 添加分页
$query .= " LIMIT {$args['per_page']} OFFSET $offset";
return $this->db->get_results($query);
}
/**
* 获取单个订单详情
* @param int $order_id 订单ID
* @return object|null 订单对象或null
*/
public function get_order($order_id) {
$table_name = $this->db->prefix . 'mom_orders';
return $this->db->get_row($this->db->prepare(
"SELECT * FROM $table_name WHERE id = %d",
$order_id
));
}
/**
* 更新订单
* @param int $order_id 订单ID
* @param array $data 更新数据
* @return bool 是否成功
*/
public function update_order($order_id, $data) {
$table_name = $this->db->prefix . 'mom_orders';
return $this->db->update(
$table_name,
$data,
array('id' => $order_id),
array('%s', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s'),
array('%d')
);
}
/**
* 删除订单
* @param int $order_id 订单ID
* @return bool 是否成功
*/
public function delete_order($order_id) {
$table_name = $this->db->prefix . 'mom_orders';
return $this->db->delete(
$table_name,
array('id' => $order_id),
array('%d')
);
}
/**
* 获取订单统计
* @return array 统计信息
*/
public function get_order_stats() {
$table_name = $this->db->prefix . 'mom_orders';
$stats = array();
// 总订单数
$stats['total_orders'] = $this->db->get_var("SELECT COUNT(*) FROM $table_name");
// 总金额
$stats['total_revenue'] = $this->db->get_var("SELECT SUM(total_amount) FROM $table_name WHERE status NOT IN ('cancelled', 'refunded')");
// 按状态统计
$status_counts = $this->db->get_results("SELECT status, COUNT(*) as count FROM $table_name GROUP BY status");
foreach ($status_counts as $status) {
$stats['status_counts'][$status->status] = $status->count;
}
return $stats;
}
}
includes/class-admin-page.php
<?php
/**
* 后台管理页面类
* 处理插件在WordPress后台的显示和功能
*/
class MOM_Admin_Page {
public function __construct() {
// 添加管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
// 主菜单
add_menu_page(
'订单管理', // 页面标题
'订单管理', // 菜单标题
'manage_options', // 权限
'mom-orders', // 菜单slug
array($this, 'display_orders_page'), // 回调函数
'dashicons-cart', // 图标
30 // 位置
);
// 子菜单:所有订单
add_submenu_page(
'mom-orders',
'所有订单',
'所有订单',
'manage_options',
'mom-orders',
array($this, 'display_orders_page')
);
// 子菜单:添加新订单
add_submenu_page(
'mom-orders',
'添加新订单',
'添加新订单',
'manage_options',
'mom-add-order',
array($this, 'display_add_order_page')
);
// 子菜单:统计
add_submenu_page(
'mom-orders',
'订单统计',
'统计',
'manage_options',
'mom-statistics',
array($this, 'display_statistics_page')
);
}
/**
* 加载后台资源
*/
public function enqueue_admin_assets($hook) {
// 只在插件页面加载
if (strpos($hook, 'mom-') === false) {
return;
}
// 加载CSS
wp_enqueue_style(
'mom-admin-style',
MOM_PLUGIN_URL . 'assets/css/admin-style.css',
array(),
MOM_PLUGIN_VERSION
);
// 加载JS
wp_enqueue_script(
'mom-admin-script',
MOM_PLUGIN_URL . 'assets/js/admin-script.js',
array('jquery'),
MOM_PLUGIN_VERSION,
true
);
// 本地化脚本,传递数据到JS
wp_localize_script('mom-admin-script', 'mom_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('mom_ajax_nonce')
));
}
/**
* 显示订单列表页面
*/
public function display_orders_page() {
// 实例化订单类
$orders_manager = new MOM_Orders();
// 获取当前页和状态筛选
$current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
$status_filter = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : '';
$search_term = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
// 获取订单数据
$args = array(
'per_page' => 20,
'page' => $current_page,
'status' => $status_filter,
search_term
);
$orders = $orders_manager->get_orders($args);
$total_orders = $orders_manager->get_order_stats()['total_orders'];
$total_pages = ceil($total_orders / $args['per_page']);
// 获取所有状态
$database = new MOM_Database();
$statuses = $database->get_order_statuses();
?>
<div class="wrap mom-admin-wrap">
<h1 class="wp-heading-inline">订单管理</h1>
<a href="<?php echo admin_url('admin.php?page=mom-add-order'); ?>" class="page-title-action">添加新订单</a>
<!-- 搜索和筛选表单 -->
<div class="mom-filters">
<form method="get" action="<?php echo admin_url('admin.php'); ?>">
<input type="hidden" name="page" value="mom-orders">
<div class="search-box">
<input type="search" name="s" value="<?php echo esc_attr($search_term); ?>" placeholder="搜索订单号、客户姓名或邮箱">
<input type="submit" class="button" value="搜索">
</div>
<div class="status-filter">
<select name="status" onchange="this.form.submit()">
<option value="">所有状态</option>
<?php foreach ($statuses as $status): ?>
<option value="<?php echo esc_attr($status->status_key); ?>"
<?php selected($status_filter, $status->status_key); ?>>
<?php echo esc_html($status->status_label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</form>
</div>
<!-- 订单列表表格 -->
<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 if (empty($orders)): ?>
<tr>
<td colspan="6" style="text-align: center;">暂无订单</td>
</tr>
<?php else: ?>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo esc_html($order->order_number); ?></td>
<td><?php echo esc_html($order->customer_name); ?></td>
<td><?php echo date('Y-m-d H:i', strtotime($order->order_date)); ?></td>
<td><?php echo number_format($order->total_amount, 2); ?>元</td>
<td>
<span class="order-status status-<?php echo esc_attr($order->status); ?>">
<?php
$status_label = '';
foreach ($statuses as $status) {
if ($status->status_key == $order->status) {
$status_label = $status->status_label;
break;
}
}
echo esc_html($status_label);
?>
</span>
</td>
<td>
<a href="<?php echo admin_url('admin.php?page=mom-add-order&order_id=' . $order->id); ?>" class="button button-small">编辑</a>
<a href="#" class="button button-small button-delete" data-order-id="<?php echo $order->id; ?>">删除</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<!-- 分页 -->
<?php if ($total_pages > 1): ?>
<div class="tablenav bottom">
<div class="tablenav-pages">
<span class="displaying-num">共 <?php echo $total_orders; ?> 个订单</span>
<span class="pagination-links">
<?php
$base_url = admin_url('admin.php?page=mom-orders');
if ($status_filter) $base_url .= '&status=' . $status_filter;
if ($search_term) $base_url .= '&s=' . urlencode($search_term);
if ($current_page > 1) {
echo '<a class="first-page button" href="' . $base_url . '&paged=1">«</a>';
echo '<a class="prev-page button" href="' . $base_url . '&paged=' . ($current_page - 1) . '">‹</a>';
}
echo '<span class="paging-input">';
echo '<input class="current-page" type="text" size="2" value="' . $current_page . '" name="paged">';
echo ' 页,共 <span class="total-pages">' . $total_pages . '</span> 页';
echo '</span>';
if ($current_page < $total_pages) {
echo '<a class="next-page button" href="' . $base_url . '&paged=' . ($current_page + 1) . '">›</a>';
echo '<a class="last-page button" href="' . $base_url . '&paged=' . $total_pages . '">»</a>';
}
?>
</span>
</div>
</div>
<?php endif; ?>
</div>
<?php
}
/**
* 显示添加/编辑订单页面
*/
public function display_add_order_page() {
$orders_manager = new MOM_Orders();
$database = new MOM_Database();
$statuses = $database->get_order_statuses();
$order_id = isset($_GET['order_id']) ? intval($_GET['order_id']) : 0;
$order = $order_id ? $orders_manager->get_order($order_id) : null;
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mom_save_order'])) {
$this->save_order($order_id);
$order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
$order = $order_id ? $orders_manager->get_order($order_id) : null;
}
?>
<div class="wrap">
<h1><?php echo $order ? '编辑订单' : '添加新订单'; ?></h1>
<form method="post" action="">
<?php wp_nonce_field('mom_save_order', 'mom_order_nonce'); ?>
<input type="hidden" name="order_id" value="<?php echo $order ? $order->id : 0; ?>">
<div class="mom-form-container">
<div class="mom-form-section">
<h2>订单信息</h2>
<table class="form-table">
<tr>
<th><label for="order_number">订单号</label></th>
<td>
<input type="text" id="order_number" name="order_number"
value="<?php echo $order ? esc_attr($order->order_number) : ''; ?>"
class="regular-text" required>
<p class="description">系统将自动生成订单号,如需自定义可修改</p>
</td>
</tr>
<tr>
<th><label for="order_date">订单日期</label></th>
<td>
<input type="datetime-local" id="order_date" name="order_date"
value="<?php echo $order ? date('Y-m-dTH:i', strtotime($order->order_date)) : date('Y-m-dTH:i'); ?>"
class="regular-text" required>
</td>
</tr>
<tr>
<th><label for="status">订单状态</label></th>
<td>
<select id="status" name="status" class="regular-text">
<?php foreach ($statuses as $status): ?>
<option value="<?php echo esc_attr($status->status_key); ?>"
<?php echo ($order && $order->status == $status->status_key) ? 'selected' : ''; ?>>
<?php echo esc_html($status->status_label); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
</table>
</div>
<div class="mom-form-section">
<h2>客户信息</h2>
<table class="form-table">
<tr>
<th><label for="customer_name">客户姓名</label></th>
<td>
<input type="text" id="customer_name" name="customer_name"
value="<?php echo $order ? esc_attr($order->customer_name) : ''; ?>"
class="regular-text" required>
</td>
</tr>
<tr>
<th><label for="customer_email">客户邮箱</label></th>
<td>
<input type="email" id="customer_email" name="customer_email"
value="<?php echo $order ? esc_attr($order->customer_email) : ''; ?>"
class="regular-text">
</td>
</tr>
<tr>
<th><label for="customer_phone">客户电话</label></th>
<td>
<input type="tel" id="customer_phone" name="customer_phone"
value="<?php echo $order ? esc_attr($order->customer_phone) : ''; ?>"
class="regular-text">
</td>
</tr>
</table>
</div>
<div class="mom-form-section">
<h2>订单详情</h2>
<table class="form-table">
<tr>
<th><label for="total_amount">订单总额</label></th>
<td>
<input type="number" id="total_amount" name="total_amount"
value="<?php echo $order ? esc_attr($order->total_amount) : '0.00'; ?>"
step="0.01" min="0" class="small-text" required> 元
</td>
</tr>
<tr>
<th><label for="payment_method">支付方式</label></th>
<td>
<select id="payment_method" name="payment_method" class="regular-text">
<option value="">请选择支付方式</option>
<option value="alipay" <?php echo ($order && $order->payment_method == 'alipay') ? 'selected' : ''; ?>>支付宝</option>
<option value="wechat" <?php echo ($order && $order->payment_method == 'wechat') ? 'selected' : ''; ?>>微信支付</option>
<option value="bank" <?php echo ($order && $order->payment_method == 'bank') ? 'selected' : ''; ?>>银行转账</option>
<option value="cash" <?php echo ($order && $order->payment_method == 'cash') ? 'selected' : ''; ?>>现金</option>
</select>
</td>
</tr>
<tr>
<th><label for="notes">备注</label></th>
<td>
<textarea id="notes" name="notes" rows="4" class="large-text"><?php echo $order ? esc_textarea($order->notes) : ''; ?></textarea>
</td>
</tr>
</table>
</div>
<div class="submit">
<input type="submit" name="mom_save_order" class="button button-primary" value="保存订单">
<a href="<?php echo admin_url('admin.php?page=mom-orders'); ?>" class="button">返回订单列表</a>
</div>
</div>
</form>
</div>
<?php
}
/**
* 保存订单
*/
private function save_order($order_id) {
// 验证nonce
if (!isset($_POST['mom_order_nonce']) || !wp_verify_nonce($_POST['mom_order_nonce'], 'mom_save_order')) {
wp_die('安全验证失败');
}
// 验证权限
if (!current_user_can('manage_options')) {
wp_die('权限不足');
}
// 准备订单数据
$order_data = array(
'order_number' => sanitize_text_field($_POST['order_number']),
'customer_name' => sanitize_text_field($_POST['customer_name']),
'customer_email' => sanitize_email($_POST['customer_email']),
'customer_phone' => sanitize_text_field($_POST['customer_phone']),
'order_date' => sanitize_text_field($_POST['order_date']),
'total_amount' => floatval($_POST['total_amount']),
'status' => sanitize_text_field($_POST['status']),
'payment_method' => sanitize_text_field($_POST['payment_method']),
'notes' => sanitize_textarea_field($_POST['notes'])
);
$orders_manager = new MOM_Orders();
if ($order_id) {
// 更新订单
$result = $orders_manager->update_order($order_id, $order_data);
if ($result) {
add_action('admin_notices', function() {
echo '<div class="notice notice-success is-dismissible"><p>订单更新成功!</p></div>';
});
}
} else {
// 创建新订单
$new_order_id = $orders_manager->create_order($order_data);
if ($new_order_id) {
add_action('admin_notices', function() {
echo '<div class="notice notice-success is-dismissible"><p>订单创建成功!</p></div>';
});
}
}
}
/**
* 显示统计页面
*/
public function display_statistics_page() {
$orders_manager = new MOM_Orders();
$stats = $orders_manager->get_order_stats();
// 获取最近30天的订单数据
global $wpdb;
$table_name = $wpdb->prefix . 'mom_orders';
$thirty_days_ago = date('Y-m-d', strtotime('-30 days'));
$daily_stats = $wpdb->get_results($wpdb->prepare(
"SELECT DATE(order_date) as date, COUNT(*) as count, SUM(total_amount) as revenue
FROM $table_name
WHERE order_date >= %s
GROUP BY DATE(order_date)
ORDER BY date DESC",
$thirty_days_ago
));
?>
<div class="wrap">
<h1>订单统计</h1>
<div class="mom-stats-container">
<div class="mom-stats-overview">
<div class="stat-box">
<h3>总订单数</h3>
<div class="stat-number"><?php echo esc_html($stats['total_orders']); ?></div>
</div>
<div class="stat-box">
<h3>总销售额</h3>
<div class="stat-number"><?php echo number_format($stats['total_revenue'], 2); ?>元</div>
</div>
<div class="stat-box">
<h3>平均订单额</h3>
<div class="stat-number">
<?php
$avg = $stats['total_orders'] > 0 ? $stats['total_revenue'] / $stats['total_orders'] : 0;
echo number_format($avg, 2); ?>元
</div>
</div>
</div>
<div class="mom-stats-details">
<h2>订单状态分布</h2>
<table class="wp-list-table widefat fixed">
<thead>
<tr>
<th>状态</th>
<th>订单数</th>
<th>占比</th>
</tr>
</thead>
<tbody>
<?php
$total_orders = $stats['total_orders'];
if (isset($stats['status_counts'])) {
foreach ($stats['status_counts'] as $status => $count) {
$percentage = $total_orders > 0 ? ($count / $total_orders * 100) : 0;
?>
<tr>
<td><?php echo esc_html($status); ?></td>
<td><?php echo esc_html($count); ?></td>
<td><?php echo number_format($percentage, 1); ?>%</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
</div>
<div class="mom-stats-chart">
<h2>最近30天订单趋势</h2>
<table class="wp-list-table widefat fixed">
<thead>
<tr>
<th>日期</th>
<th>订单数</th>
<th>销售额</th>
</tr>
</thead>
<tbody>
<?php if (empty($daily_stats)): ?>
<tr>
<td colspan="3" style="text-align: center;">暂无数据</td>
</tr>
<?php else: ?>
<?php foreach ($daily_stats as $daily): ?>
<tr>
<td><?php echo esc_html($daily->date); ?></td>
<td><?php echo esc_html($daily->count); ?></td>
<td><?php echo number_format($daily->revenue, 2); ?>元</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="mom-export-section">
<h2>数据导出</h2>
<p>导出订单数据为CSV格式:</p>
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
<input type="hidden" name="action" value="mom_export_orders">
<?php wp_nonce_field('mom_export_nonce'); ?>
<label


