文章目录[隐藏]
WordPress小批量定制插件实现智能排产的技术教程
概述
在制造业和项目管理中,智能排产是一个关键环节,它能够优化资源分配、提高生产效率。本教程将指导您如何在WordPress中开发一个小批量定制插件,实现智能排产功能。我们将创建一个完整的插件,包含前端表单、排产算法和结果展示。
插件结构与规划
在开始编码之前,我们先规划插件的基本结构:
- 数据库表设计 - 存储订单和排产信息
- 管理界面 - 后台管理订单和排产设置
- 前端表单 - 用户提交定制订单
- 排产算法 - 核心智能排产逻辑
- 结果展示 - 显示排产计划和甘特图
第一步:创建插件基础文件
首先,在WordPress的wp-content/plugins目录下创建新文件夹smart-production-scheduler,并创建以下文件:
<?php
/**
* Plugin Name: 智能排产系统
* Plugin URI: https://yourwebsite.com/
* Description: 小批量定制产品的智能排产插件
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('SPS_VERSION', '1.0.0');
define('SPS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SPS_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
require_once SPS_PLUGIN_DIR . 'includes/class-database.php';
require_once SPS_PLUGIN_DIR . 'includes/class-scheduler.php';
require_once SPS_PLUGIN_DIR . 'includes/class-frontend.php';
require_once SPS_PLUGIN_DIR . 'includes/class-admin.php';
// 激活和停用钩子
register_activation_hook(__FILE__, array('SPS_Database', 'create_tables'));
register_deactivation_hook(__FILE__, array('SPS_Database', 'drop_tables'));
// 初始化插件类
class Smart_Production_Scheduler {
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() {
add_action('init', array($this, 'load_textdomain'));
// 初始化各个模块
SPS_Database::init();
SPS_Scheduler::init();
SPS_Frontend::init();
SPS_Admin::init();
}
public function load_textdomain() {
load_plugin_textdomain('smart-production-scheduler', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
}
// 启动插件
Smart_Production_Scheduler::get_instance();
?>
第二步:创建数据库表
在includes/class-database.php中创建数据库表:
<?php
/**
* 数据库处理类
*/
class SPS_Database {
public static function init() {
// 数据库初始化代码
}
/**
* 创建插件所需的数据库表
*/
public static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 订单表
$orders_table = $wpdb->prefix . 'sps_orders';
$orders_sql = "CREATE TABLE IF NOT EXISTS $orders_table (
id INT(11) NOT NULL AUTO_INCREMENT,
customer_name VARCHAR(100) NOT NULL,
product_type VARCHAR(50) NOT NULL,
quantity INT(11) NOT NULL,
production_time INT(11) NOT NULL COMMENT '生产所需时间(小时)',
priority INT(11) DEFAULT 5 COMMENT '优先级,1-10,1为最高',
due_date DATE NOT NULL COMMENT '交货日期',
status VARCHAR(20) DEFAULT 'pending' COMMENT '订单状态',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 排产计划表
$schedule_table = $wpdb->prefix . 'sps_schedule';
$schedule_sql = "CREATE TABLE IF NOT EXISTS $schedule_table (
id INT(11) NOT NULL AUTO_INCREMENT,
order_id INT(11) NOT NULL,
machine_id INT(11) NOT NULL COMMENT '机器ID',
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
completed TINYINT(1) DEFAULT 0 COMMENT '是否完成',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (order_id) REFERENCES $orders_table(id) ON DELETE CASCADE
) $charset_collate;";
// 机器资源表
$machines_table = $wpdb->prefix . 'sps_machines';
$machines_sql = "CREATE TABLE IF NOT EXISTS $machines_table (
id INT(11) NOT NULL AUTO_INCREMENT,
machine_name VARCHAR(100) NOT NULL,
capacity INT(11) NOT NULL COMMENT '每小时产能',
status VARCHAR(20) DEFAULT 'available' COMMENT '机器状态',
maintenance_schedule TEXT COMMENT '维护计划',
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($orders_sql);
dbDelta($schedule_sql);
dbDelta($machines_sql);
// 插入示例机器数据
self::insert_sample_machines();
}
/**
* 插入示例机器数据
*/
private static function insert_sample_machines() {
global $wpdb;
$table = $wpdb->prefix . 'sps_machines';
$machines = array(
array('machine_name' => 'CNC机床1', 'capacity' => 10),
array('machine_name' => 'CNC机床2', 'capacity' => 8),
array('machine_name' => '3D打印机1', 'capacity' => 5),
array('machine_name' => '激光切割机', 'capacity' => 12),
);
foreach ($machines as $machine) {
$wpdb->insert($table, $machine);
}
}
/**
* 删除数据库表(插件停用时)
*/
public static function drop_tables() {
global $wpdb;
$tables = array(
$wpdb->prefix . 'sps_schedule',
$wpdb->prefix . 'sps_orders',
$wpdb->prefix . 'sps_machines',
);
foreach ($tables as $table) {
$wpdb->query("DROP TABLE IF EXISTS $table");
}
}
}
?>
第三步:实现智能排产算法
在includes/class-scheduler.php中实现核心排产算法:
<?php
/**
* 智能排产算法类
*/
class SPS_Scheduler {
public static function init() {
add_action('sps_generate_schedule', array(__CLASS__, 'generate_schedule'));
}
/**
* 智能排产主函数
* @param array $orders 订单数组
* @param array $machines 机器数组
* @return array 排产结果
*/
public static function intelligent_scheduling($orders, $machines) {
// 按优先级和交货日期排序订单
usort($orders, function($a, $b) {
if ($a['priority'] == $b['priority']) {
return strtotime($a['due_date']) - strtotime($b['due_date']);
}
return $a['priority'] - $b['priority'];
});
$schedule = array();
$machine_availability = array();
// 初始化机器可用时间
foreach ($machines as $machine) {
$machine_availability[$machine['id']] = current_time('mysql');
}
// 为每个订单分配机器
foreach ($orders as $order) {
$best_machine = self::find_best_machine($order, $machines, $machine_availability);
if ($best_machine) {
$start_time = $machine_availability[$best_machine['id']];
$end_time = self::calculate_end_time($start_time, $order['production_time']);
$schedule[] = array(
'order_id' => $order['id'],
'machine_id' => $best_machine['id'],
'start_time' => $start_time,
'end_time' => $end_time,
'order_details' => $order
);
// 更新机器可用时间
$machine_availability[$best_machine['id']] = $end_time;
}
}
return $schedule;
}
/**
* 为订单寻找最佳机器
* @param array $order 订单信息
* @param array $machines 可用机器
* @param array $availability 机器可用时间
* @return array|null 最佳机器信息
*/
private static function find_best_machine($order, $machines, $availability) {
$best_machine = null;
$best_score = PHP_INT_MAX;
foreach ($machines as $machine) {
if ($machine['status'] !== 'available') {
continue;
}
// 计算分数:基于产能和可用时间
$capacity_score = $order['production_time'] / $machine['capacity'];
$availability_time = strtotime($availability[$machine['id']]);
$time_score = $availability_time;
// 综合分数(可根据需求调整权重)
$total_score = $capacity_score * 0.7 + $time_score * 0.3;
if ($total_score < $best_score) {
$best_score = $total_score;
$best_machine = $machine;
}
}
return $best_machine;
}
/**
* 计算结束时间
* @param string $start_time 开始时间
* @param int $production_hours 生产所需小时数
* @return string 结束时间
*/
private static function calculate_end_time($start_time, $production_hours) {
$start_timestamp = strtotime($start_time);
// 考虑工作时间(假设每天工作8小时)
$work_hours_per_day = 8;
$work_days_needed = ceil($production_hours / $work_hours_per_day);
// 计算实际结束时间(跳过周末)
$current_day = 0;
$hours_remaining = $production_hours;
while ($hours_remaining > 0) {
$current_timestamp = $start_timestamp + ($current_day * 86400);
$day_of_week = date('N', $current_timestamp);
// 跳过周末(6=周六,7=周日)
if ($day_of_week < 6) {
$hours_today = min($work_hours_per_day, $hours_remaining);
$hours_remaining -= $hours_today;
}
$current_day++;
}
$end_timestamp = $start_timestamp + ($current_day * 86400);
return date('Y-m-d H:i:s', $end_timestamp);
}
/**
* 生成排产计划
*/
public static function generate_schedule() {
global $wpdb;
// 获取待排产的订单
$orders_table = $wpdb->prefix . 'sps_orders';
$orders = $wpdb->get_results(
"SELECT * FROM $orders_table WHERE status = 'pending' ORDER BY priority, due_date",
ARRAY_A
);
// 获取可用机器
$machines_table = $wpdb->prefix . 'sps_machines';
$machines = $wpdb->get_results(
"SELECT * FROM $machines_table WHERE status = 'available'",
ARRAY_A
);
if (empty($orders) || empty($machines)) {
return false;
}
// 执行智能排产
$schedule = self::intelligent_scheduling($orders, $machines);
// 保存排产结果到数据库
$schedule_table = $wpdb->prefix . 'sps_schedule';
foreach ($schedule as $item) {
$wpdb->insert($schedule_table, array(
'order_id' => $item['order_id'],
'machine_id' => $item['machine_id'],
'start_time' => $item['start_time'],
'end_time' => $item['end_time']
));
// 更新订单状态
$wpdb->update(
$orders_table,
array('status' => 'scheduled'),
array('id' => $item['order_id'])
);
}
return $schedule;
}
}
?>
第四步:创建前端表单
在includes/class-frontend.php中创建用户提交订单的表单:
<?php
/**
* 前端处理类
*/
class SPS_Frontend {
public static function init() {
add_shortcode('sps_order_form', array(__CLASS__, 'order_form_shortcode'));
add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'));
add_action('wp_ajax_sps_submit_order', array(__CLASS__, 'ajax_submit_order'));
add_action('wp_ajax_nopriv_sps_submit_order', array(__CLASS__, 'ajax_submit_order'));
}
/**
* 订单表单短代码
*/
public static function order_form_shortcode() {
ob_start();
?>
<div class="sps-order-form-container">
<h3>提交定制订单</h3>
<form id="sps-order-form" method="post">
<?php wp_nonce_field('sps_submit_order', 'sps_nonce'); ?>
<div class="form-group">
<label for="customer_name">客户名称 *</label>
<input type="text" id="customer_name" name="customer_name" required>
</div>
<div class="form-group">
<label for="product_type">产品类型 *</label>
<select id="product_type" name="product_type" required>
<option value="">请选择</option>
<option value="metal_part">金属零件</option>
<option value="plastic_part">塑料零件</option>
<option value="electronic_assembly">电子装配</option>
<option value="custom_prototype">定制原型</option>
</select>
</div>
<div class="form-group">
<label for="quantity">数量 *</label>
<input type="number" id="quantity" name="quantity" min="1" max="1000" required>
<small>小批量定制:1-1000件</small>
</div>
<div class="form-group">
<label for="production_time">预计生产时间(小时) *</label>
<input type="number" id="production_time" name="production_time" min="1" max="500" required>
</div>
<div class="form-group">
<label for="priority">优先级 *</label>
<select id="priority" name="priority" required>
<option value="1">最高 (1)</option>
<option value="3">高 (3)</option>
<option value="5" selected>中 (5)</option>
<option value="7">低 (7)</option>
<option value="10">最低 (10)</option>
</select>
</div>
<div class="form-group">
<label for="due_date">期望交货日期 *</label>
<input type="date" id="due_date" name="due_date" required>
</div>
<div class="form-group">
<label for="notes">备注</label>
<textarea id="notes" name="notes" rows="3"></textarea>
</div>
<button type="submit" class="sps-submit-btn">提交订单</button>
<div id="sps-response-message"></div>
</form>
</div>
<style>
.sps-order-form-container {
max-width: 600px;
margin: 20px auto;
padding: 20px;
background: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.sps-submit-btn {
background: #0073aa;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.sps-submit-btn:hover {
background: #005a87;
}
#sps-response-message {
margin-top: 15px;
padding: 10px;
border-radius: 4px;
}
.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
</style>
<?php
return ob_get_clean();
}
/**
* 提交订单的AJAX处理
*/
public static function ajax_submit_order() {
// 验证nonce
if (!wp_verify_nonce($_POST['sps_nonce'], 'sps_submit_order')) {
wp_die('安全验证失败');
}
// 验证数据
$required_fields = array('customer_name', 'product_type', 'quantity', 'production_time', 'priority', 'due_date');
foreach ($required_fields as $field) {
if (empty($_POST[$field])) {
wp_send_json_error('请填写所有必填字段');
}
}
global $wpdb;
$table = $wpdb->prefix . 'sps_orders';
// 准备数据
$order_data = array(
'customer_name' => sanitize_text_field($_POST['customer_name']),
'product_type' => sanitize_text_field($_POST['product_type']),
'quantity' => intval($_POST['quantity']),
'production_time' => intval($_POST['production_time']),
'priority' => intval($_POST['priority']),
'due_date' => sanitize_text_field($_POST['due_date']),
'status' => 'pending'
);
// 插入数据库
$result = $wpdb->insert($table, $order_data);
if ($result) {
// 触发排产计划生成(可以设置为定时任务或手动触发)
do_action('sps_generate_schedule');
wp_send_json_success(array(
'message' => '订单提交成功!订单ID:' . $wpdb->insert_id,
'order_id' => $wpdb->insert_id
));
} else {
wp_send_json_error('订单提交失败,请重试');
}
}
/**
* 加载前端脚本和样式
*/
public static function enqueue_scripts() {
wp_enqueue_style('sps-frontend-style', SPS_PLUGIN_URL . 'assets/css/frontend.css');
wp_enqueue_script('sps-frontend-script', SPS_PLUGIN_URL . 'assets/js/frontend.js', array('jquery'), SPS_VERSION, true);
wp_localize_script('sps-frontend-script', 'sps_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('sps_submit_order')
));
}
}
?>
第五步:创建管理后台界面
在includes/class-admin.php中创建管理界面:
<?php
/**
* 后台管理类
*/
class SPS_Admin {
public static function init() {
add_action('admin_menu', array(__CLASS__, 'add_admin_menu'));
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_admin_scripts'));
add_action('admin_post_generate_schedule', array(__CLASS__, 'handle_generate_schedule'));
}
/**
* 添加管理菜单
*/
public static function add_admin_menu() {
add_menu_page(
'智能排产系统',
'智能排产',
'manage_options',
'smart-production-scheduler',
array(__CLASS__, 'display_dashboard'),
'dashicons-schedule',
30
);
add_submenu_page(
'smart-production-scheduler',
'订单管理',
'订单管理',
'manage_options',
'sps-orders',
array(__CLASS__, 'display_orders_page')
);
add_submenu_page(
'smart-production-scheduler',
'排产计划',
'排产计划',
'manage_options',
'sps-schedule',
array(__CLASS__, 'display_schedule_page')
);
add_submenu_page(
'smart-production-scheduler',
'机器管理',
'机器管理',
'manage_options',
'sps-machines',
array(__CLASS__, 'display_machines_page')
);
add_submenu_page(
'smart-production-scheduler',
'排产设置',
'排产设置',
'manage_options',
'sps-settings',
array(__CLASS__, 'display_settings_page')
);
}
/**
* 显示仪表板
*/
public static function display_dashboard() {
global $wpdb;
// 获取统计数据
$orders_table = $wpdb->prefix . 'sps_orders';
$schedule_table = $wpdb->prefix . 'sps_schedule';
$machines_table = $wpdb->prefix . 'sps_machines';
$total_orders = $wpdb->get_var("SELECT COUNT(*) FROM $orders_table");
$pending_orders = $wpdb->get_var("SELECT COUNT(*) FROM $orders_table WHERE status = 'pending'");
$completed_orders = $wpdb->get_var("SELECT COUNT(*) FROM $orders_table WHERE status = 'completed'");
$active_machines = $wpdb->get_var("SELECT COUNT(*) FROM $machines_table WHERE status = 'available'");
?>
<div class="wrap">
<h1>智能排产系统仪表板</h1>
<div class="sps-dashboard-widgets">
<div class="sps-widget">
<h3>总订单数</h3>
<p class="sps-stat"><?php echo $total_orders; ?></p>
</div>
<div class="sps-widget">
<h3>待处理订单</h3>
<p class="sps-stat"><?php echo $pending_orders; ?></p>
</div>
<div class="sps-widget">
<h3>已完成订单</h3>
<p class="sps-stat"><?php echo $completed_orders; ?></p>
</div>
<div class="sps-widget">
<h3>可用机器</h3>
<p class="sps-stat"><?php echo $active_machines; ?></p>
</div>
</div>
<div class="sps-dashboard-actions">
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
<input type="hidden" name="action" value="generate_schedule">
<?php wp_nonce_field('generate_schedule_action', 'generate_schedule_nonce'); ?>
<button type="submit" class="button button-primary button-large">
立即生成排产计划
</button>
</form>
</div>
<div class="sps-recent-orders">
<h2>最近订单</h2>
<?php self::display_orders_table(5); ?>
</div>
<div class="sps-upcoming-schedule">
<h2>即将开始的排产</h2>
<?php self::display_upcoming_schedule(); ?>
</div>
</div>
<style>
.sps-dashboard-widgets {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.sps-widget {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
text-align: center;
}
.sps-stat {
font-size: 2em;
font-weight: bold;
color: #0073aa;
margin: 10px 0;
}
.sps-dashboard-actions {
margin: 30px 0;
padding: 20px;
background: white;
border-radius: 8px;
}
</style>
<?php
}
/**
* 显示订单管理页面
*/
public static function display_orders_page() {
global $wpdb;
$table = $wpdb->prefix . 'sps_orders';
// 处理批量操作
if (isset($_POST['action']) && $_POST['action'] == 'bulk_action') {
self::handle_bulk_actions();
}
// 获取订单数据
$orders = $wpdb->get_results("SELECT * FROM $table ORDER BY created_at DESC", ARRAY_A);
?>
<div class="wrap">
<h1>订单管理</h1>
<form method="post" action="">
<?php wp_nonce_field('bulk_action', 'bulk_action_nonce'); ?>
<div class="tablenav top">
<div class="alignleft actions bulkactions">
<select name="bulk_action">
<option value="">批量操作</option>
<option value="delete">删除</option>
<option value="mark_completed">标记为完成</option>
<option value="mark_pending">标记为待处理</option>
</select>
<button type="submit" class="button action">应用</button>
</div>
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th class="check-column"><input type="checkbox" id="cb-select-all"></th>
<th>ID</th>
<th>客户名称</th>
<th>产品类型</th>
<th>数量</th>
<th>生产时间</th>
<th>优先级</th>
<th>交货日期</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<th scope="row"><input type="checkbox" name="order_ids[]" value="<?php echo $order['id']; ?>"></th>
<td><?php echo $order['id']; ?></td>
<td><?php echo esc_html($order['customer_name']); ?></td>
<td><?php echo esc_html($order['product_type']); ?></td>
<td><?php echo $order['quantity']; ?></td>
<td><?php echo $order['production_time']; ?> 小时</td>
<td>
<span class="priority-badge priority-<?php echo $order['priority']; ?>">
<?php echo $order['priority']; ?>
</span>
</td>
<td><?php echo $order['due_date']; ?></td>
<td>
<span class="status-badge status-<?php echo $order['status']; ?>">
<?php echo self::get_status_label($order['status']); ?>
</span>
</td>
<td><?php echo $order['created_at']; ?></td>
<td>
<a href="#" class="button button-small view-order" data-id="<?php echo $order['id']; ?>">查看</a>
<a href="#" class="button button-small delete-order" data-id="<?php echo $order['id']; ?>">删除</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</form>
</div>
<style>
.priority-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.priority-1, .priority-2, .priority-3 {
background: #ff6b6b;
color: white;
}
.priority-4, .priority-5, .priority-6 {
background: #ffd93d;
color: #333;
}
.priority-7, .priority-8, .priority-9, .priority-10 {
background: #6bcf7f;
color: white;
}
.status-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.status-pending {
background: #ffd93d;
color: #333;
}
.status-scheduled {
background: #4d96ff;
color: white;
}
.status-completed {
background: #6bcf7f;
color: white;
}
</style>
<script>
jQuery(document).ready(function($) {
// 全选/取消全选
$('#cb-select-all').on('change', function() {
$('input[name="order_ids[]"]').prop('checked', this.checked);
});
// 查看订单详情
$('.view-order').on('click', function(e) {
e.preventDefault();
var orderId = $(this).data('id');
// 这里可以添加查看详情的逻辑
alert('查看订单 ' + orderId + ' 的详情');
});
// 删除订单
$('.delete-order').on('click', function(e) {
e.preventDefault();
if (confirm('确定要删除这个订单吗?')) {
var orderId = $(this).data('id');
// 这里可以添加删除订单的AJAX请求
}
});
});
</script>
<?php
}
/**
* 显示排产计划页面
*/
public static function display_schedule_page() {
global $wpdb;
$schedule_table = $wpdb->prefix . 'sps_schedule';
$orders_table = $wpdb->prefix . 'sps_orders';
$machines_table = $wpdb->prefix . 'sps_machines';
// 获取排产数据
$schedule = $wpdb->get_results("
SELECT s.*, o.customer_name, o.product_type, m.machine_name
FROM $schedule_table s
LEFT JOIN $orders_table o ON s.order_id = o.id
LEFT JOIN $machines_table m ON s.machine_id = m.id
ORDER BY s.start_time ASC
", ARRAY_A);
?>
<div class="wrap">
<h1>排产计划</h1>
<div class="sps-gantt-chart">
<h2>甘特图</h2>
<div class="gantt-container">
<?php foreach ($schedule as $item):
$start_date = new DateTime($item['start_time']);
$end_date = new DateTime($item['end_time']);
$duration = $start_date->diff($end_date)->days;
?>
<div class="gantt-item" style="margin-left: <?php echo $duration * 10; ?>px; width: <?php echo max(50, $duration * 20); ?>px;">
<div class="gantt-bar">
<span class="gantt-label">
<?php echo esc_html($item['customer_name']); ?> -
<?php echo esc_html($item['product_type']); ?>
</span>
</div>
<div class="gantt-info">
机器: <?php echo esc_html($item['machine_name']); ?><br>
开始: <?php echo $item['start_time']; ?><br>
结束: <?php echo $item['end_time']; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>订单ID</th>
<th>客户名称</th>
<th>产品类型</th>
<th>机器</th>
<th>开始时间</th>
<th>结束时间</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($schedule as $item): ?>
<tr>
<td><?php echo $item['order_id']; ?></td>
<td><?php echo esc_html($item['customer_name']); ?></td>
<td><?php echo esc_html($item['product_type']); ?></td>
<td><?php echo esc_html($item['machine_name']); ?></td>
<td><?php echo $item['start_time']; ?></td>
<td><?php echo $item['end_time']; ?></td>
<td>
<?php if ($item['completed']): ?>
<span class="status-badge status-completed">已完成</span>
<?php else: ?>
<span class="status-badge status-scheduled">已排产</span>
<?php endif; ?>
</td>
<td>
<button class="button button-small mark-completed" data-id="<?php echo $item['id']; ?>">
<?php echo $item['completed'] ? '取消完成' : '标记完成'; ?>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<style>
.sps-gantt-chart {
margin: 20px 0;
padding: 20px;
background: white;
border-radius: 8px;
}
.gantt-container {
padding: 20px;
background: #f5f5f5;
border-radius: 4px;
overflow-x: auto;
}
.gantt-item {
margin: 10px 0;
position: relative;
}
.gantt-bar {
background: #4d96ff;
color: white;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
.gantt-bar:hover {
background: #2d76df;
}
.gantt-info {
display: none;
position: absolute;
