WordPress小批量定制插件实现动态产能规划的教程
引言:为什么需要动态产能规划插件
在当今快速变化的商业环境中,制造企业和小型工作室面临着共同的挑战:如何根据实时订单和资源情况动态调整生产计划。传统的静态产能规划方法已无法满足小批量、多品种的生产需求。本教程将指导您开发一个WordPress定制插件,帮助企业实现动态产能规划,提高资源利用率,减少库存积压。
通过这个插件,企业可以在WordPress后台直观地查看产能状况,根据实时数据调整生产计划,并自动生成生产排程建议。我们将从零开始构建这个插件,确保代码完整且带有详细注释。
环境准备与插件基础结构
首先,我们需要创建插件的基本文件结构。在WordPress的wp-content/plugins/目录下创建一个新文件夹dynamic-capacity-planner。
<?php
/**
* Plugin Name: 动态产能规划系统
* Plugin URI: https://yourwebsite.com/
* Description: 用于小批量生产的动态产能规划工具
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: dynamic-capacity
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('DCP_VERSION', '1.0.0');
define('DCP_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('DCP_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class DynamicCapacityPlanner {
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('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
public function activate() {
// 创建数据库表
$this->create_tables();
// 添加默认数据
$this->add_default_data();
// 设置默认选项
update_option('dcp_capacity_unit', '件/小时');
update_option('dcp_work_hours_per_day', 8);
update_option('dcp_work_days_per_week', 5);
}
public function deactivate() {
// 清理临时数据
// 注意:这里不删除主要数据,以便重新激活时可以使用
}
public function init() {
// 初始化代码
load_plugin_textdomain('dynamic-capacity', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
// 其他方法将在下面逐步添加
}
// 启动插件
DynamicCapacityPlanner::get_instance();
?>
数据库设计与数据模型
接下来,我们需要设计数据库表来存储产能规划相关数据。在activate方法中调用的create_tables函数需要实现:
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 产品表
$products_table = $wpdb->prefix . 'dcp_products';
$products_sql = "CREATE TABLE IF NOT EXISTS $products_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
description text,
standard_time decimal(5,2) NOT NULL COMMENT '标准生产时间(小时)',
setup_time decimal(5,2) DEFAULT 0 COMMENT '准备时间(小时)',
min_batch_size int DEFAULT 1 COMMENT '最小批量',
max_batch_size int DEFAULT 100 COMMENT '最大批量',
status tinyint(1) DEFAULT 1 COMMENT '1=启用, 0=禁用',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 资源表(机器、人员等)
$resources_table = $wpdb->prefix . 'dcp_resources';
$resources_sql = "CREATE TABLE IF NOT EXISTS $resources_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
type varchar(50) NOT NULL COMMENT 'machine, labor, material',
capacity decimal(10,2) NOT NULL COMMENT '产能(单位/小时)',
availability decimal(5,2) DEFAULT 100 COMMENT '可用性百分比',
cost_per_hour decimal(10,2) DEFAULT 0,
status tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 订单表
$orders_table = $wpdb->prefix . 'dcp_orders';
$orders_sql = "CREATE TABLE IF NOT EXISTS $orders_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
order_number varchar(50) NOT NULL,
product_id mediumint(9) NOT NULL,
quantity int NOT NULL,
due_date date NOT NULL,
priority tinyint(1) DEFAULT 2 COMMENT '1=高, 2=中, 3=低',
status varchar(20) DEFAULT 'pending' COMMENT 'pending, scheduled, in_progress, completed',
scheduled_start_date date,
scheduled_end_date date,
actual_start_date date,
actual_end_date date,
notes text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (product_id) REFERENCES $products_table(id) ON DELETE CASCADE
) $charset_collate;";
// 生产计划表
$schedules_table = $wpdb->prefix . 'dcp_schedules';
$schedules_sql = "CREATE TABLE IF NOT EXISTS $schedules_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
order_id mediumint(9) NOT NULL,
resource_id mediumint(9) NOT NULL,
start_time datetime NOT NULL,
end_time datetime NOT NULL,
actual_start_time datetime,
actual_end_time datetime,
efficiency decimal(5,2) DEFAULT 100 COMMENT '生产效率百分比',
notes text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (order_id) REFERENCES $orders_table(id) ON DELETE CASCADE,
FOREIGN KEY (resource_id) REFERENCES $resources_table(id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($products_sql);
dbDelta($resources_sql);
dbDelta($orders_sql);
dbDelta($schedules_sql);
}
管理界面与产能可视化
现在,让我们创建插件管理界面。我们将添加一个主菜单和几个子菜单:
public function add_admin_menu() {
// 主菜单
add_menu_page(
'动态产能规划',
'产能规划',
'manage_options',
'dynamic-capacity',
array($this, 'render_dashboard_page'),
'dashicons-chart-area',
30
);
// 子菜单
add_submenu_page(
'dynamic-capacity',
'产能仪表板',
'仪表板',
'manage_options',
'dynamic-capacity',
array($this, 'render_dashboard_page')
);
add_submenu_page(
'dynamic-capacity',
'产品管理',
'产品管理',
'manage_options',
'dcp-products',
array($this, 'render_products_page')
);
add_submenu_page(
'dynamic-capacity',
'资源管理',
'资源管理',
'manage_options',
'dcp-resources',
array($this, 'render_resources_page')
);
add_submenu_page(
'dynamic-capacity',
'订单管理',
'订单管理',
'manage_options',
'dcp-orders',
array($this, 'render_orders_page')
);
add_submenu_page(
'dynamic-capacity',
'生产计划',
'生产计划',
'manage_options',
'dcp-schedules',
array($this, 'render_schedules_page')
);
add_submenu_page(
'dynamic-capacity',
'产能分析',
'产能分析',
'manage_options',
'dcp-analytics',
array($this, 'render_analytics_page')
);
}
public function render_dashboard_page() {
?>
<div class="wrap">
<h1>动态产能规划仪表板</h1>
<div class="dcp-dashboard">
<div class="dcp-stats-row">
<div class="dcp-stat-box">
<h3>今日产能利用率</h3>
<div class="dcp-stat-value"><?php echo $this->get_today_capacity_utilization(); ?>%</div>
<div class="dcp-stat-trend">较昨日: <?php echo $this->get_capacity_trend(); ?>%</div>
</div>
<div class="dcp-stat-box">
<h3>待处理订单</h3>
<div class="dcp-stat-value"><?php echo $this->get_pending_orders_count(); ?></div>
<div class="dcp-stat-detail">总计: <?php echo $this->get_total_orders_count(); ?> 个订单</div>
</div>
<div class="dcp-stat-box">
<h3>可用资源</h3>
<div class="dcp-stat-value"><?php echo $this->get_available_resources_count(); ?></div>
<div class="dcp-stat-detail"><?php echo $this->get_resources_breakdown(); ?></div>
</div>
<div class="dcp-stat-box">
<h3>本周计划产量</h3>
<div class="dcp-stat-value"><?php echo $this->get_weekly_planned_output(); ?></div>
<div class="dcp-stat-detail"><?php echo $this->get_capacity_unit(); ?></div>
</div>
</div>
<div class="dcp-chart-row">
<div class="dcp-chart-container">
<h3>未来7天产能负荷</h3>
<canvas id="capacityLoadChart" width="400" height="200"></canvas>
</div>
<div class="dcp-chart-container">
<h3>资源利用率分布</h3>
<canvas id="resourceUtilizationChart" width="400" height="200"></canvas>
</div>
</div>
<div class="dcp-alerts-row">
<h3>系统提醒</h3>
<div id="dcp-alerts-container">
<?php $this->display_system_alerts(); ?>
</div>
</div>
</div>
</div>
<?php
}
动态产能计算核心算法
这是插件的核心部分,实现动态产能计算和排程算法:
/**
* 计算订单所需的总生产时间
* @param int $product_id 产品ID
* @param int $quantity 订单数量
* @return array 包含总时间、准备时间和单位时间的数组
*/
public function calculate_order_time($product_id, $quantity) {
global $wpdb;
$products_table = $wpdb->prefix . 'dcp_products';
// 获取产品信息
$product = $wpdb->get_row($wpdb->prepare(
"SELECT standard_time, setup_time, min_batch_size, max_batch_size
FROM $products_table WHERE id = %d AND status = 1",
$product_id
));
if (!$product) {
return array('error' => '产品不存在或已禁用');
}
// 验证批量大小
if ($quantity < $product->min_batch_size) {
return array('error' => sprintf('订单数量不能小于最小批量(%d)', $product->min_batch_size));
}
if ($quantity > $product->max_batch_size) {
return array('error' => sprintf('订单数量不能大于最大批量(%d)', $product->max_batch_size));
}
// 计算生产时间
$setup_time = floatval($product->setup_time); // 准备时间
$unit_time = floatval($product->standard_time); // 单位产品生产时间
$total_production_time = $unit_time * $quantity; // 总生产时间
// 考虑学习曲线效应(小批量生产通常有学习曲线)
$learning_factor = $this->calculate_learning_factor($quantity);
$adjusted_production_time = $total_production_time * $learning_factor;
// 总时间 = 准备时间 + 调整后的生产时间
$total_time = $setup_time + $adjusted_production_time;
return array(
'total_time' => round($total_time, 2),
'setup_time' => round($setup_time, 2),
'unit_time' => round($unit_time, 2),
'adjusted_unit_time' => round($adjusted_production_time / $quantity, 2),
'learning_factor' => round($learning_factor, 3)
);
}
/**
* 计算学习曲线因子
* @param int $quantity 生产数量
* @return float 学习曲线因子
*/
private function calculate_learning_factor($quantity) {
// 学习曲线模型:生产数量每增加一倍,单位时间减少固定百分比
// 这里使用85%学习曲线(常见于制造业)
$learning_rate = 0.85;
if ($quantity <= 1) {
return 1.0;
}
// 计算学习曲线因子
$log_learning_rate = log($learning_rate);
$log_2 = log(2);
$exponent = $log_learning_rate / $log_2;
// 学习曲线公式:Y = a * X^b
// 其中b = log(学习率)/log(2)
$factor = pow($quantity, $exponent);
// 标准化到0.8-1.0范围
$normalized_factor = 0.8 + (0.2 * ($factor / $quantity));
return min(1.0, max(0.5, $normalized_factor));
}
/**
* 动态产能规划算法
* @param array $orders 订单数组
* @param array $resources 资源数组
* @param string $start_date 开始日期
* @param int $planning_horizon 规划周期(天)
* @return array 生产计划
*/
public function dynamic_capacity_planning($orders, $resources, $start_date, $planning_horizon = 7) {
// 初始化结果
$schedule = array();
$resource_availability = array();
// 初始化资源可用时间
foreach ($resources as $resource) {
$resource_availability[$resource['id']] = array();
for ($i = 0; $i < $planning_horizon; $i++) {
$current_date = date('Y-m-d', strtotime($start_date . " +$i days"));
$resource_availability[$resource['id']][$current_date] = array(
'available_hours' => $resource['daily_capacity'],
'booked_hours' => 0,
'tasks' => array()
);
}
}
// 按优先级和交期排序订单
usort($orders, function($a, $b) {
// 首先按优先级(数字越小优先级越高)
if ($a['priority'] != $b['priority']) {
return $a['priority'] - $b['priority'];
}
// 然后按交期(越早交期优先级越高)
return strtotime($a['due_date']) - strtotime($b['due_date']);
});
// 为每个订单安排生产
foreach ($orders as $order) {
$order_scheduled = false;
// 计算订单所需时间
$time_calculation = $this->calculate_order_time($order['product_id'], $order['quantity']);
if (isset($time_calculation['error'])) {
// 记录错误,继续处理下一个订单
$schedule['errors'][] = "订单 {$order['id']}: " . $time_calculation['error'];
continue;
}
$required_hours = $time_calculation['total_time'];
// 尝试为订单安排生产
foreach ($resources as $resource) {
if (!$this->is_resource_suitable($resource, $order)) {
continue;
}
$resource_id = $resource['id'];
// 寻找最早可用的时间段
for ($i = 0; $i < $planning_horizon; $i++) {
$current_date = date('Y-m-d', strtotime($start_date . " +$i days"));
// 检查资源在该日期是否有足够可用时间
if ($resource_availability[$resource_id][$current_date]['available_hours'] >= $required_hours) {
// 安排生产
$task = array(
'order_id' => $order['id'],
'order_number' => $order['order_number'],
'product_id' => $order['product_id'],
'quantity' => $order['quantity'],
'required_hours' => $required_hours,
'start_date' => $current_date,
'end_date' => $current_date,
'resource_id' => $resource_id,
'resource_name' => $resource['name']
);
// 更新资源可用性
available_hours'] -= $required_hours;
$resource_availability[$resource_id][$current_date]['booked_hours'] += $required_hours;
$resource_availability[$resource_id][$current_date]['tasks'][] = $task;
// 添加到总计划
$schedule['tasks'][] = $task;
$order_scheduled = true;
// 记录排程日期
$schedule['order_dates'][$order['id']] = $current_date;
break 2; // 跳出资源循环和日期循环
}
}
}
// 如果无法在规划周期内安排,尝试拆分订单
if (!$order_scheduled) {
$split_schedule = $this->split_order_across_days($order, $resources, $resource_availability, $start_date, $planning_horizon);
if ($split_schedule) {
$schedule['tasks'] = array_merge($schedule['tasks'], $split_schedule['tasks']);
$schedule['order_dates'][$order['id']] = $split_schedule['scheduled_date'];
$schedule['split_orders'][] = $order['id'];
} else {
$schedule['unscheduled'][] = array(
'order_id' => $order['id'],
'order_number' => $order['order_number'],
'required_hours' => $required_hours,
'reason' => '规划周期内资源不足'
);
}
}
}
// 计算资源利用率统计
$schedule['resource_stats'] = $this->calculate_resource_statistics($resource_availability, $resources, $planning_horizon);
return $schedule;
}
/**
- 检查资源是否适合生产特定订单
- @param array $resource 资源信息
- @param array $order 订单信息
- @return bool 是否适合
*/
private function is_resource_suitable($resource, $order) {
// 这里可以根据实际业务逻辑扩展
// 例如:检查资源类型、技能匹配、设备兼容性等
// 简单示例:检查资源状态
if ($resource['status'] != 1) {
return false;
}
// 检查资源可用性
if ($resource['availability'] < 80) { // 可用性低于80%的资源不推荐使用
return false;
}
// 可以添加更多检查条件
// if ($resource['type'] == 'machine' && !in_array($order['product_type'], $resource['capabilities'])) {
// return false;
// }
return true;
}
/**
- 将订单拆分到多天生产
- @param array $order 订单信息
- @param array $resources 资源数组
- @param array $resource_availability 资源可用性
- @param string $start_date 开始日期
- @param int $planning_horizon 规划周期
- @return array|bool 拆分后的计划或false
*/
private function split_order_across_days($order, $resources, &$resource_availability, $start_date, $planning_horizon) {
$time_calculation = $this->calculate_order_time($order['product_id'], $order['quantity']);
if (isset($time_calculation['error'])) {
return false;
}
$required_hours = $time_calculation['total_time'];
$remaining_hours = $required_hours;
$scheduled_tasks = array();
$scheduled_date = null;
// 尝试找到合适的资源
foreach ($resources as $resource) {
if (!$this->is_resource_suitable($resource, $order)) {
continue;
}
$resource_id = $resource['id'];
// 在规划周期内寻找可用时间段
for ($i = 0; $i < $planning_horizon && $remaining_hours > 0; $i++) {
$current_date = date('Y-m-d', strtotime($start_date . " +$i days"));
$available_hours = $resource_availability[$resource_id][$current_date]['available_hours'];
if ($available_hours > 0) {
$hours_to_schedule = min($available_hours, $remaining_hours);
// 创建任务
$task = array(
'order_id' => $order['id'],
'order_number' => $order['order_number'],
'product_id' => $order['product_id'],
'quantity' => $order['quantity'],
'required_hours' => $hours_to_schedule,
'start_date' => $current_date,
'end_date' => $current_date,
'resource_id' => $resource_id,
'resource_name' => $resource['name'],
'is_split' => true,
'split_part' => count($scheduled_tasks) + 1
);
// 更新资源可用性
$resource_availability[$resource_id][$current_date]['available_hours'] -= $hours_to_schedule;
$resource_availability[$resource_id][$current_date]['booked_hours'] += $hours_to_schedule;
$resource_availability[$resource_id][$current_date]['tasks'][] = $task;
$scheduled_tasks[] = $task;
$remaining_hours -= $hours_to_schedule;
if ($scheduled_date === null) {
$scheduled_date = $current_date;
}
}
}
if ($remaining_hours <= 0) {
break;
}
}
if ($remaining_hours <= 0) {
return array(
'tasks' => $scheduled_tasks,
'scheduled_date' => $scheduled_date
);
}
return false;
}
## 前端交互与数据可视化
为了让用户更好地理解产能规划结果,我们需要添加数据可视化功能:
/**
- 渲染产能分析页面
*/
public function render_analytics_page() {
// 获取分析数据
$capacity_data = $this->get_capacity_analytics_data();
$resource_data = $this->get_resource_utilization_data();
$order_trends = $this->get_order_trends_data();
?>
<div class="wrap">
<h1>产能分析报告</h1>
<div class="dcp-analytics-container">
<!-- 时间范围选择器 -->
<div class="dcp-date-range-selector">
<form method="get" action="">
<input type="hidden" name="page" value="dcp-analytics">
<label for="start_date">开始日期:</label>
<input type="date" id="start_date" name="start_date"
value="<?php echo isset($_GET['start_date']) ? esc_attr($_GET['start_date']) : date('Y-m-d', strtotime('-30 days')); ?>">
<label for="end_date">结束日期:</label>
<input type="date" id="end_date" name="end_date"
value="<?php echo isset($_GET['end_date']) ? esc_attr($_GET['end_date']) : date('Y-m-d'); ?>">
<button type="submit" class="button button-primary">应用筛选</button>
</form>
</div>
<!-- 关键指标 -->
<div class="dcp-kpi-container">
<div class="dcp-kpi-card">
<h4>平均产能利用率</h4>
<div class="dcp-kpi-value"><?php echo $capacity_data['avg_utilization']; ?>%</div>
<div class="dcp-kpi-trend <?php echo $capacity_data['utilization_trend'] >= 0 ? 'positive' : 'negative'; ?>">
<?php echo $capacity_data['utilization_trend'] >= 0 ? '↑' : '↓'; ?>
<?php echo abs($capacity_data['utilization_trend']); ?>%
</div>
</div>
<div class="dcp-kpi-card">
<h4>准时交付率</h4>
<div class="dcp-kpi-value"><?php echo $capacity_data['on_time_delivery']; ?>%</div>
<div class="dcp-kpi-trend <?php echo $capacity_data['delivery_trend'] >= 0 ? 'positive' : 'negative'; ?>">
<?php echo $capacity_data['delivery_trend'] >= 0 ? '↑' : '↓'; ?>
<?php echo abs($capacity_data['delivery_trend']); ?>%
</div>
</div>
<div class="dcp-kpi-card">
<h4>平均生产周期</h4>
<div class="dcp-kpi-value"><?php echo $capacity_data['avg_cycle_time']; ?>天</div>
<div class="dcp-kpi-trend <?php echo $capacity_data['cycle_time_trend'] <= 0 ? 'positive' : 'negative'; ?>">
<?php echo $capacity_data['cycle_time_trend'] <= 0 ? '↓' : '↑'; ?>
<?php echo abs($capacity_data['cycle_time_trend']); ?>天
</div>
</div>
<div class="dcp-kpi-card">
<h4>资源综合效率</h4>
<div class="dcp-kpi-value"><?php echo $capacity_data['overall_efficiency']; ?>%</div>
<div class="dcp-kpi-trend <?php echo $capacity_data['efficiency_trend'] >= 0 ? 'positive' : 'negative'; ?>">
<?php echo $capacity_data['efficiency_trend'] >= 0 ? '↑' : '↓'; ?>
<?php echo abs($capacity_data['efficiency_trend']); ?>%
</div>
</div>
</div>
<!-- 图表区域 -->
<div class="dcp-charts-container">
<div class="dcp-chart-wrapper">
<h3>产能利用率趋势</h3>
<canvas id="utilizationTrendChart" height="250"></canvas>
</div>
<div class="dcp-chart-wrapper">
<h3>资源负载分布</h3>
<canvas id="resourceLoadChart" height="250"></canvas>
</div>
<div class="dcp-chart-wrapper">
<h3>订单类型分布</h3>
<canvas id="orderTypeChart" height="250"></canvas>
</div>
<div class="dcp-chart-wrapper">
<h3>生产效率分析</h3>
<canvas id="efficiencyChart" height="250"></canvas>
</div>
</div>
<!-- 详细数据表格 -->
<div class="dcp-data-table">
<h3>详细产能数据</h3>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>日期</th>
<th>计划产能</th>
<th>实际产出</th>
<th>利用率</th>
<th>资源数量</th>
<th>订单数量</th>
<th>平均周期</th>
</tr>
</thead>
<tbody>
<?php foreach ($capacity_data['daily_details'] as $day): ?>
<tr>
<td><?php echo $day['date']; ?></td>
<td><?php echo $day['planned_capacity']; ?></td>
<td><?php echo $day['actual_output']; ?></td>
<td>
<div class="dcp-utilization-bar">
<div class="dcp-utilization-fill" style="width: <?php echo $day['utilization']; ?>%"></div>
<span><?php echo $day['utilization']; ?>%</span>
</div>
</td>
<td><?php echo $day['resource_count']; ?></td>
<td><?php echo $day['order_count']; ?></td>
<td><?php echo $day['avg_cycle_time']; ?>天</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- JavaScript代码 -->
<script>
jQuery(document).ready(function($) {
// 产能利用率趋势图
var utilizationCtx = document.getElementById('utilizationTrendChart').getContext('2d');
var utilizationChart = new Chart(utilizationCtx, {
type: 'line',
data: {
labels: <?php echo json_encode($capacity_data['chart_labels']); ?>,
datasets: [{
label: '产能利用率',
data: <?php echo json_encode($capacity_data['utilization_data']); ?>,
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgba(75, 192, 192, 0.1)',
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
}
},
scales: {
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function(value) {
return value + '%';
}
}
}
}
}
});
// 资源负载分布图
var resourceCtx = document.getElementById('resourceLoadChart').getContext('2d');
var resourceChart = new Chart(resourceCtx, {
type: 'bar',
data: {
labels: <?php echo json_encode($resource_data['labels']); ?>,
datasets: [{
label: '资源负载率',
data: <?php echo json_encode($resource_data['load_rates']); ?>,
backgroundColor: [
'rgba(255, 99, 132, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(75, 192, 192, 0.7)',
'rgba(153, 102, 255, 0.7)'
]
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
max: 100,
ticks: {
callback: function(value) {
return value + '%';
}
}
}
}
}
});
});
</script>
<?php
}
/**
- 获取产能分析数据
*/
private function get_capacity_analytics_data() {
global $wpdb;
$start_date = isset($_GET['start_date']) ? sanitize_text_field($_GET['start_date']) : date('Y-m-d', strtotime('-30 days'));
$end_date = isset($_GET['end_date']) ? sanitize_text_field($_GET['end_date']) : date('Y-m-d');
// 这里应该从数据库获取实际数据
// 以下是示例数据
$data = array(
'avg_utilization' => 78.5,
'utilization_trend' => 2.3,
'on_time_delivery' => 92.1,
'delivery_trend' => 1.2,
'avg_cycle_time' => 3.2,
'cycle_time_trend' => -0.5,
'overall_efficiency' => 85.7,
'efficiency_trend' => 1.8,
'chart_labels' => ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
'utilization_data' => [75, 78, 82, 80, 85, 70, 65],
'daily_details' => array()
);
// 生成示例每日数据
$current_date = $start_date;
while (strtotime($current_date) <= strtotime($end_date)) {
$data['daily_details'][] = array(
'date' => $current_date,
'planned_capacity' => rand(800, 1200),
'actual_output' => rand(700, 1100),
'utilization' => rand(70, 95),
'resource_count' => rand(5, 15),
'order_count' => rand(10, 30),
'avg_cycle_time' => rand(2, 5) + (rand(0, 9) / 10)
);
$current_date = date('Y-m-d', strtotime($current_date . ' +1 day'));
}
return $data;
}
## 插件配置与优化建议
最后,我们需要添加插件配置页面和一些优化功能:
/**
- 添加插件设置页面
*/
public function add_settings_page() {
add_submenu_page(
'dynamic-capacity',
'插件设置',
'设置',
'manage_options',
'dcp-settings',
array($this, 'render_settings_page')
);
}
/**
- 渲染设置页面
*/
public function render_settings_page() {
// 保存设置
if (isset($_POST['submit_dcp_settings'])) {
check_admin_referer('dcp_settings_nonce');
// 保存基本设置
update_option('dcp_capacity_unit', sanitize_text_field($_POST['capacity_unit']));
update_option('dcp_work_hours_per_day', floatval($_POST['work_hours_per_day']));
update_option('dcp_work_days_per_week', intval($_POST['work_days_per_week']));
update_option('dcp_default_learning_rate', floatval($_POST['default_learning_rate']));
update_option('dcp_min_utilization_alert', intval($_POST['min_utilization_alert']));
update_option('dcp_max_utilization_alert', intval($_POST['max_utilization_alert']));
// 保存通知设置
$notification_settings = array(
'capacity_alerts' => isset($_POST['capacity_alerts']) ? 1 : 0,
'schedule_changes' => isset($_POST['schedule_changes']) ? 1 : 0,
