实现小批量生产跟踪的WordPress插件开发教程
概述
在当今数字化制造时代,小批量生产跟踪对于中小型制造企业至关重要。本教程将指导您开发一个功能完整的WordPress插件,帮助企业跟踪小批量生产订单的状态、进度和库存。这个插件将包含订单管理、生产进度跟踪、库存管理和报告生成等核心功能。
插件基础结构
首先,我们需要创建插件的基本文件结构。在WordPress的wp-content/plugins/目录下创建一个新文件夹small-batch-production-tracker。
主插件文件
<?php
/**
* 插件名称: Small Batch Production Tracker
* 插件URI: https://example.com/small-batch-tracker
* 描述: 一个小批量生产跟踪和管理插件
* 版本: 1.0.0
* 作者: Your Name
* 作者URI: https://example.com
* 许可证: GPL v2或更高版本
* 文本域: small-batch-tracker
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('SBPT_VERSION', '1.0.0');
define('SBPT_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SBPT_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class SmallBatchProductionTracker {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活和停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('init', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate() {
// 创建数据库表
$this->create_database_tables();
// 设置默认选项
add_option('sbpt_version', SBPT_VERSION);
}
public function deactivate() {
// 清理临时数据
// 注意:这里我们不删除数据,以便用户重新激活时保留数据
}
public function load_textdomain() {
load_plugin_textdomain('small-batch-tracker', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
public function init() {
// 初始化代码
}
public function add_admin_menu() {
// 添加管理菜单
add_menu_page(
__('小批量生产跟踪', 'small-batch-tracker'),
__('生产跟踪', 'small-batch-tracker'),
'manage_options',
'sbpt-dashboard',
array($this, 'render_dashboard_page'),
'dashicons-clipboard',
30
);
// 子菜单项
add_submenu_page(
'sbpt-dashboard',
__('订单管理', 'small-batch-tracker'),
__('订单管理', 'small-batch-tracker'),
'manage_options',
'sbpt-orders',
array($this, 'render_orders_page')
);
add_submenu_page(
'sbpt-dashboard',
__('库存管理', 'small-batch-tracker'),
__('库存管理', 'small-batch-tracker'),
'manage_options',
'sbpt-inventory',
array($this, 'render_inventory_page')
);
add_submenu_page(
'sbpt-dashboard',
__('报告', 'small-batch-tracker'),
__('报告', 'small-batch-tracker'),
'manage_options',
'sbpt-reports',
array($this, 'render_reports_page')
);
add_submenu_page(
'sbpt-dashboard',
__('设置', 'small-batch-tracker'),
__('设置', 'small-batch-tracker'),
'manage_options',
'sbpt-settings',
array($this, 'render_settings_page')
);
}
// 创建数据库表
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_prefix = $wpdb->prefix . 'sbpt_';
// 订单表
$orders_table = $table_prefix . 'orders';
$orders_sql = "CREATE TABLE IF NOT EXISTS $orders_table (
id INT(11) NOT NULL AUTO_INCREMENT,
order_number VARCHAR(50) NOT NULL,
customer_name VARCHAR(100) NOT NULL,
product_name VARCHAR(200) NOT NULL,
quantity INT(11) NOT NULL,
status ENUM('pending', 'in_production', 'completed', 'shipped', 'cancelled') DEFAULT 'pending',
priority ENUM('low', 'medium', 'high') DEFAULT 'medium',
start_date DATE,
estimated_completion DATE,
actual_completion DATE,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY order_number (order_number)
) $charset_collate;";
// 库存表
$inventory_table = $table_prefix . 'inventory';
$inventory_sql = "CREATE TABLE IF NOT EXISTS $inventory_table (
id INT(11) NOT NULL AUTO_INCREMENT,
material_name VARCHAR(100) NOT NULL,
sku VARCHAR(50) NOT NULL,
current_stock INT(11) NOT NULL DEFAULT 0,
minimum_stock INT(11) NOT NULL DEFAULT 10,
unit VARCHAR(20) NOT NULL,
location VARCHAR(100),
supplier VARCHAR(100),
last_restocked DATE,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY sku (sku)
) $charset_collate;";
// 生产日志表
$production_log_table = $table_prefix . 'production_log';
$production_log_sql = "CREATE TABLE IF NOT EXISTS $production_log_table (
id INT(11) NOT NULL AUTO_INCREMENT,
order_id INT(11) NOT NULL,
log_type ENUM('status_change', 'note', 'issue', 'completion') NOT NULL,
message TEXT NOT NULL,
logged_by VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY order_id (order_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($orders_sql);
dbDelta($inventory_sql);
dbDelta($production_log_sql);
}
// 渲染页面方法
public function render_dashboard_page() {
include SBPT_PLUGIN_DIR . 'templates/dashboard.php';
}
public function render_orders_page() {
include SBPT_PLUGIN_DIR . 'templates/orders.php';
}
public function render_inventory_page() {
include SBPT_PLUGIN_DIR . 'templates/inventory.php';
}
public function render_reports_page() {
include SBPT_PLUGIN_DIR . 'templates/reports.php';
}
public function render_settings_page() {
include SBPT_PLUGIN_DIR . 'templates/settings.php';
}
}
// 初始化插件
SmallBatchProductionTracker::get_instance();
?>
订单管理功能实现
订单数据操作类
<?php
// 文件路径: includes/class-order-manager.php
class SBPT_Order_Manager {
/**
* 添加新订单
* @param array $order_data 订单数据
* @return int|false 成功返回订单ID,失败返回false
*/
public static function add_order($order_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_orders';
// 验证必需字段
$required_fields = ['order_number', 'customer_name', 'product_name', 'quantity'];
foreach ($required_fields as $field) {
if (empty($order_data[$field])) {
return false;
}
}
// 设置默认值
$defaults = [
'status' => 'pending',
'priority' => 'medium',
'start_date' => current_time('Y-m-d'),
'notes' => ''
];
$order_data = wp_parse_args($order_data, $defaults);
// 插入数据
$result = $wpdb->insert(
$table_name,
$order_data,
['%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s']
);
if ($result) {
$order_id = $wpdb->insert_id;
// 记录生产日志
self::add_production_log($order_id, 'status_change',
sprintf(__('订单创建,状态设置为: %s', 'small-batch-tracker'),
self::get_status_label($order_data['status'])));
return $order_id;
}
return false;
}
/**
* 更新订单状态
* @param int $order_id 订单ID
* @param string $new_status 新状态
* @return bool 成功返回true,失败返回false
*/
public static function update_order_status($order_id, $new_status) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_orders';
// 获取当前状态
$current_status = $wpdb->get_var(
$wpdb->prepare("SELECT status FROM $table_name WHERE id = %d", $order_id)
);
if ($current_status === $new_status) {
return true; // 状态未改变
}
// 更新状态
$result = $wpdb->update(
$table_name,
['status' => $new_status],
['id' => $order_id],
['%s'],
['%d']
);
if ($result) {
// 如果是完成状态,设置完成日期
if ($new_status === 'completed') {
$wpdb->update(
$table_name,
['actual_completion' => current_time('Y-m-d')],
['id' => $order_id],
['%s'],
['%d']
);
}
// 记录状态变更日志
self::add_production_log(
$order_id,
'status_change',
sprintf(
__('状态从 %s 变更为 %s', 'small-batch-tracker'),
self::get_status_label($current_status),
self::get_status_label($new_status)
)
);
return true;
}
return false;
}
/**
* 获取所有订单
* @param array $args 查询参数
* @return array 订单数组
*/
public static function get_orders($args = []) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_orders';
$defaults = [
'status' => '',
'limit' => 50,
'offset' => 0,
'orderby' => 'created_at',
'order' => 'DESC'
];
$args = wp_parse_args($args, $defaults);
$where = '';
$prepare_values = [];
if (!empty($args['status'])) {
$where = "WHERE status = %s";
$prepare_values[] = $args['status'];
}
$query = "SELECT * FROM $table_name $where
ORDER BY {$args['orderby']} {$args['order']}
LIMIT %d OFFSET %d";
$prepare_values[] = $args['limit'];
$prepare_values[] = $args['offset'];
if (!empty($prepare_values)) {
$query = $wpdb->prepare($query, $prepare_values);
}
return $wpdb->get_results($query, ARRAY_A);
}
/**
* 获取订单统计
* @return array 统计数组
*/
public static function get_order_stats() {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_orders';
$stats = [];
// 按状态统计
$status_stats = $wpdb->get_results(
"SELECT status, COUNT(*) as count FROM $table_name GROUP BY status",
ARRAY_A
);
foreach ($status_stats as $stat) {
$stats[$stat['status']] = $stat['count'];
}
// 总订单数
$stats['total'] = array_sum($stats);
// 本周新增订单
$week_start = date('Y-m-d', strtotime('monday this week'));
$stats['this_week'] = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM $table_name WHERE created_at >= %s",
$week_start
)
);
return $stats;
}
/**
* 添加生产日志
* @param int $order_id 订单ID
* @param string $log_type 日志类型
* @param string $message 日志消息
* @return bool 成功返回true,失败返回false
*/
private static function add_production_log($order_id, $log_type, $message) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_production_log';
$current_user = wp_get_current_user();
$logged_by = $current_user->display_name;
return $wpdb->insert(
$table_name,
[
'order_id' => $order_id,
'log_type' => $log_type,
'message' => $message,
'logged_by' => $logged_by
],
['%d', '%s', '%s', '%s']
);
}
/**
* 获取状态标签
* @param string $status 状态代码
* @return string 状态标签
*/
public static function get_status_label($status) {
$labels = [
'pending' => __('待处理', 'small-batch-tracker'),
'in_production' => __('生产中', 'small-batch-tracker'),
'completed' => __('已完成', 'small-batch-tracker'),
'shipped' => __('已发货', 'small-batch-tracker'),
'cancelled' => __('已取消', 'small-batch-tracker')
];
return isset($labels[$status]) ? $labels[$status] : $status;
}
}
?>
前端订单管理界面
<?php
// 文件路径: templates/orders.php
// 检查用户权限
if (!current_user_can('manage_options')) {
wp_die(__('您没有权限访问此页面。', 'small-batch-tracker'));
}
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_order'])) {
// 添加新订单
$order_data = [
'order_number' => sanitize_text_field($_POST['order_number']),
'customer_name' => sanitize_text_field($_POST['customer_name']),
'product_name' => sanitize_text_field($_POST['product_name']),
'quantity' => intval($_POST['quantity']),
'priority' => sanitize_text_field($_POST['priority']),
'estimated_completion' => sanitize_text_field($_POST['estimated_completion']),
'notes' => sanitize_textarea_field($_POST['notes'])
];
$result = SBPT_Order_Manager::add_order($order_data);
if ($result) {
echo '<div class="notice notice-success"><p>' .
__('订单添加成功!', 'small-batch-tracker') . '</p></div>';
} else {
echo '<div class="notice notice-error"><p>' .
__('添加订单失败,请检查必填字段。', 'small-batch-tracker') . '</p></div>';
}
}
if (isset($_POST['update_status'])) {
// 更新订单状态
$order_id = intval($_POST['order_id']);
$new_status = sanitize_text_field($_POST['new_status']);
$result = SBPT_Order_Manager::update_order_status($order_id, $new_status);
if ($result) {
echo '<div class="notice notice-success"><p>' .
__('订单状态更新成功!', 'small-batch-tracker') . '</p></div>';
} else {
echo '<div class="notice notice-error"><p>' .
__('更新失败,请重试。', 'small-batch-tracker') . '</p></div>';
}
}
}
// 获取订单数据
$orders = SBPT_Order_Manager::get_orders();
$status_options = [
'pending' => '待处理',
'in_production' => '生产中',
'completed' => '已完成',
'shipped' => '已发货',
'cancelled' => '已取消'
];
?>
<div class="wrap">
<h1><?php _e('订单管理', 'small-batch-tracker'); ?></h1>
<!-- 添加新订单表单 -->
<div class="card">
<h2><?php _e('添加新订单', 'small-batch-tracker'); ?></h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th scope="row"><?php _e('订单号', 'small-batch-tracker'); ?></th>
<td><input type="text" name="order_number" required class="regular-text"></td>
</tr>
<tr>
<th scope="row"><?php _e('客户名称', 'small-batch-tracker'); ?></th>
<td><input type="text" name="customer_name" required class="regular-text"></td>
</tr>
<tr>
<th scope="row"><?php _e('产品名称', 'small-batch-tracker'); ?></th>
<td><input type="text" name="product_name" required class="regular-text"></td>
</tr>
<tr>
<th scope="row"><?php _e('数量', 'small-batch-tracker'); ?></th>
<td><input type="number" name="quantity" required min="1" class="small-text"></td>
</tr>
<tr>
<th scope="row"><?php _e('优先级', 'small-batch-tracker'); ?></th>
<td>
<select name="priority">
<option value="low"><?php _e('低', 'small-batch-tracker'); ?></option>
<option value="medium" selected><?php _e('中', 'small-batch-tracker'); ?></option>
<option value="high"><?php _e('高', 'small-batch-tracker'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><?php _e('预计完成日期', 'small-batch-tracker'); ?></th>
<td><input type="date" name="estimated_completion" class="regular-text"></td>
</tr>
<tr>
<th scope="row"><?php _e('备注', 'small-batch-tracker'); ?></th>
<td><textarea name="notes" rows="3" class="large-text"></textarea></td>
</tr>
</table>
<p class="submit">
<input type="submit" name="add_order" class="button button-primary" value="<?php _e('添加订单', 'small-batch-tracker'); ?>">
</p>
</form>
</div>
<!-- 订单列表 -->
<div class="card">
<h2><?php _e('订单列表', 'small-batch-tracker'); ?></h2>
<!-- 状态筛选 -->
<div class="tablenav top">
<div class="alignleft actions">
<form method="get" action="">
<input type="hidden" name="page" value="sbpt-orders">
<select name="status_filter">
<option value=""><?php _e('所有状态', 'small-batch-tracker'); ?></option>
<?php foreach ($status_options as $value => $label): ?>
<option value="<?php echo esc_attr($value); ?>"
<?php selected(isset($_GET['status_filter']) && $_GET['status_filter'] === $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<input type="submit" class="button" value="<?php _e('筛选', 'small-batch-tracker'); ?>">
</form>
</div>
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th><?php _e('订单号', 'small-batch-tracker'); ?></th>
<th><?php _e('客户', 'small-batch-tracker'); ?></th>
<th><?php _e('产品', 'small-batch-tracker'); ?></th>
<th><?php _e('数量', 'small-batch-tracker'); ?></th>
<th><?php _e('状态', 'small-batch-tracker'); ?></th>
<th><?php _e('优先级', 'small-batch-tracker'); ?></th>
<th><?php _e('开始日期', 'small-batch-tracker'); ?></th>
<th><?php _e('预计完成', 'small-batch-tracker'); ?></th>
<th><?php _e('操作', 'small-batch-tracker'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($orders)): ?>
<tr>
<td colspan="9"><?php _e('暂无订单', 'small-batch-tracker'); ?></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 esc_html($order['product_name']); ?></td>
<td><?php echo esc_html($order['quantity']); ?></td>
<td>
<span class="status-badge status-<?php echo esc_attr($order['status']); ?>">
<?php echo esc_html(SBPT_Order_Manager::get_status_label($order['status'])); ?>
</span>
</td>
<td><?php echo esc_html(ucfirst($order['priority'])); ?></td>
<td><?php echo esc_html($order['start_date']); ?></td>
<td><?php echo esc_html($order['estimated_completion']); ?></td>
<td>
<form method="post" action="" style="display: inline;">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<select name="new_status" style="width: 120px;">
<?php foreach ($status_options as $value => $label): ?>
<option value="<?php echo esc_attr($value); ?>"
<?php selected($order['status'] === $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<input type="submit" name="update_status" class="button button-small"
value="<?php _e('更新', 'small-batch-tracker'); ?>">
</form>
<a href="<?php echo admin_url('admin.php?page=sbpt-orders&view=details&id=' . $order['id']); ?>"
class="button button-small"><?php _e('详情', 'small-batch-tracker'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<style>
.status-badge {
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.status-pending { background: #f0ad4e; color: white; }
.status-in_production { background: #5bc0de; color: white; }
.status-completed { background: #5cb85c; color: white; }
.status-shipped { background: #337ab7; color: white; }
.status-cancelled { background: #d9534f; color: white; }
</style>
## 库存管理模块
<?php
// 文件路径: includes/class-inventory-manager.php
class SBPT_Inventory_Manager {
/**
* 添加或更新库存项目
* @param array $item_data 库存数据
* @param int|null $item_id 项目ID(更新时使用)
* @return int|false 成功返回项目ID,失败返回false
*/
public static function save_inventory_item($item_data, $item_id = null) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_inventory';
// 验证必需字段
$required_fields = ['material_name', 'sku'];
foreach ($required_fields as $field) {
if (empty($item_data[$field])) {
return false;
}
}
// 设置默认值
$defaults = [
'current_stock' => 0,
'minimum_stock' => 10,
'unit' => '个',
'location' => '',
'supplier' => '',
'notes' => ''
];
$item_data = wp_parse_args($item_data, $defaults);
if ($item_id) {
// 更新现有项目
$result = $wpdb->update(
$table_name,
$item_data,
['id' => $item_id],
['%s', '%s', '%d', '%d', '%s', '%s', '%s', '%s']
);
if ($result !== false) {
return $item_id;
}
} else {
// 插入新项目
$result = $wpdb->insert(
$table_name,
$item_data,
['%s', '%s', '%d', '%d', '%s', '%s', '%s', '%s']
);
if ($result) {
return $wpdb->insert_id;
}
}
return false;
}
/**
* 更新库存数量
* @param int $item_id 项目ID
* @param int $quantity_change 数量变化(正数为增加,负数为减少)
* @param string $reason 变更原因
* @return bool 成功返回true,失败返回false
*/
public static function update_stock($item_id, $quantity_change, $reason = '') {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_inventory';
// 获取当前库存
$current_stock = $wpdb->get_var(
$wpdb->prepare("SELECT current_stock FROM $table_name WHERE id = %d", $item_id)
);
if ($current_stock === null) {
return false; // 项目不存在
}
// 计算新库存
$new_stock = $current_stock + $quantity_change;
// 更新库存
$result = $wpdb->update(
$table_name,
[
'current_stock' => $new_stock,
'updated_at' => current_time('mysql')
],
['id' => $item_id],
['%d', '%s'],
['%d']
);
if ($result) {
// 记录库存变更日志
self::log_stock_change($item_id, $quantity_change, $reason);
// 检查库存预警
self::check_stock_alert($item_id, $new_stock);
return true;
}
return false;
}
/**
* 获取库存项目
* @param array $args 查询参数
* @return array 库存项目数组
*/
public static function get_inventory_items($args = []) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_inventory';
$defaults = [
'low_stock_only' => false,
'limit' => 100,
'offset' => 0,
'orderby' => 'material_name',
'order' => 'ASC'
];
$args = wp_parse_args($args, $defaults);
$where = '';
$prepare_values = [];
if ($args['low_stock_only']) {
$where = "WHERE current_stock <= minimum_stock";
}
$query = "SELECT * FROM $table_name $where
ORDER BY {$args['orderby']} {$args['order']}
LIMIT %d OFFSET %d";
$prepare_values[] = $args['limit'];
$prepare_values[] = $args['offset'];
if (!empty($prepare_values)) {
$query = $wpdb->prepare($query, $prepare_values);
}
return $wpdb->get_results($query, ARRAY_A);
}
/**
* 获取库存统计
* @return array 统计数组
*/
public static function get_inventory_stats() {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_inventory';
$stats = [];
// 总项目数
$stats['total_items'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
// 低库存项目数
$stats['low_stock_items'] = $wpdb->get_var(
"SELECT COUNT(*) FROM $table_name WHERE current_stock <= minimum_stock"
);
// 总库存价值(假设每个项目价值为1)
$stats['total_value'] = $wpdb->get_var("SELECT SUM(current_stock) FROM $table_name");
// 缺货项目数
$stats['out_of_stock'] = $wpdb->get_var(
"SELECT COUNT(*) FROM $table_name WHERE current_stock = 0"
);
return $stats;
}
/**
* 记录库存变更日志
* @param int $item_id 项目ID
* @param int $quantity_change 数量变化
* @param string $reason 变更原因
* @return bool 成功返回true,失败返回false
*/
private static function log_stock_change($item_id, $quantity_change, $reason) {
global $wpdb;
$log_table = $wpdb->prefix . 'sbpt_stock_log';
// 确保日志表存在
self::create_stock_log_table();
$current_user = wp_get_current_user();
return $wpdb->insert(
$log_table,
[
'item_id' => $item_id,
'quantity_change' => $quantity_change,
'reason' => $reason,
'changed_by' => $current_user->display_name,
'changed_at' => current_time('mysql')
],
['%d', '%d', '%s', '%s', '%s']
);
}
/**
* 检查库存预警
* @param int $item_id 项目ID
* @param int $current_stock 当前库存
*/
private static function check_stock_alert($item_id, $current_stock) {
global $wpdb;
$table_name = $wpdb->prefix . 'sbpt_inventory';
// 获取最低库存要求
$minimum_stock = $wpdb->get_var(
$wpdb->prepare("SELECT minimum_stock FROM $table_name WHERE id = %d", $item_id)
);
// 如果库存低于最低要求,发送预警
if ($current_stock <= $minimum_stock) {
// 这里可以添加邮件通知或系统通知
// 例如:wp_mail() 发送给管理员
}
}
/**
* 创建库存日志表
*/
private static function create_stock_log_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'sbpt_stock_log';
// 检查表是否存在
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$sql = "CREATE TABLE $table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
item_id INT(11) NOT NULL,
quantity_change INT(11) NOT NULL,
reason VARCHAR(255),
changed_by VARCHAR(100),
changed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY item_id (item_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
}
?>
## 仪表板页面实现
<?php
// 文件路径: templates/dashboard.php
// 检查用户权限
if (!current_user_can('manage_options')) {
wp_die(__('您没有权限访问此页面。', 'small-batch-tracker'));
}
// 获取统计数据
$order_stats = SBPT_Order_Manager::get_order_stats();
$inventory_stats = SBPT_Inventory_Manager::get_inventory_stats();
// 获取最近订单
$recent_orders = SBPT_Order_Manager::get_orders(['limit' => 5]);
// 获取低库存项目
$low_stock_items = SBPT_Inventory_Manager::get_inventory_items(['low_stock_only' => true, 'limit' => 5]);
?>
<div class="wrap">
<h1><?php _e('生产跟踪仪表板', 'small-batch-tracker'); ?></h1>
<!-- 统计卡片 -->
<div class="sbpt-stats-container">
<div class="sbpt-stat-card">
<h3><?php _e('总订单数', 'small-batch-tracker'); ?></h3>
<div class="stat-number"><?php echo esc_html($order_stats['total']); ?></div>
<div class="stat-desc"><?php _e('本周新增', 'small-batch-tracker'); ?>: <?php echo esc_html($order_stats['this_week']); ?></div>
</div>
<div class="sbpt-stat-card">
<h3><?php _e('生产中', 'small-batch-tracker'); ?></h3>
<div class="stat-number"><?php echo esc_html($order_stats['in_production'] ?? 0); ?></div>
<div class="stat-desc"><?php _e('待处理', 'small-batch-tracker'); ?>: <?php echo esc_html($order_stats['pending'] ?? 0); ?></div>
</div>
<div class="sbpt-stat-card">
<h3><?php _e('已完成', 'small-batch-tracker'); ?></h3>
<div class="stat-number"><?php echo esc_html($order_stats['completed'] ?? 0); ?></div>
<div class="stat-desc"><?php _e('已发货', 'small-batch-tracker'); ?>: <?php echo esc_html($order_stats['shipped'] ?? 0); ?></div>
</div>
<div class="sbpt-stat-card">
<
