文章目录
-
- 在现代生产制造企业中,任务派工是生产管理的核心环节。本教程将指导您开发一个WordPress定制插件,实现小批量生产任务的智能派工系统。该系统能够根据员工技能、工作负荷和任务优先级自动分配生产任务,提高生产效率。
- 首先,我们需要创建插件的基本文件结构: <?php /** * Plugin Name: 智能生产任务派工系统 * Plugin URI: https://yourwebsite.com/ * Description: 小批量生产任务智能派工解决方案 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('SPA_PLUGIN_PATH', plugin_dir_path(__FILE__)); define('SPA_PLUGIN_URL', plugin_dir_url(__FILE__)); define('SPA_VERSION', '1.0.0'); // 初始化插件 class Smart_Production_Assignment { 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_plugin')); register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin')); // 初始化 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_plugin() { $this->create_tables(); $this->insert_default_data(); } public function deactivate_plugin() { // 清理临时数据(可选) } public function init() { // 初始化代码 } // 其他方法将在下面逐步实现 } // 启动插件 Smart_Production_Assignment::get_instance(); ?>
- 智能派工系统需要存储员工信息、任务数据和派工记录: // 在activate_plugin方法中调用 private function create_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); // 员工技能表 $table_employees = $wpdb->prefix . 'spa_employees'; $sql_employees = "CREATE TABLE IF NOT EXISTS $table_employees ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, skill_level TINYINT(3) DEFAULT 1 COMMENT '技能等级 1-5', current_workload INT(11) DEFAULT 0 COMMENT '当前工作量', max_daily_tasks INT(11) DEFAULT 5 COMMENT '每日最大任务数', specialization VARCHAR(100) COMMENT '专长领域', is_active TINYINT(1) DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) $charset_collate;"; // 生产任务表 $table_tasks = $wpdb->prefix . 'spa_tasks'; $sql_tasks = "CREATE TABLE IF NOT EXISTS $table_tasks ( id INT(11) NOT NULL AUTO_INCREMENT, task_name VARCHAR(200) NOT NULL, description TEXT, required_skill TINYINT(3) DEFAULT 1 COMMENT '所需技能等级', estimated_time INT(11) COMMENT '预计耗时(分钟)', priority TINYINT(2) DEFAULT 2 COMMENT '优先级 1-高 2-中 3-低', status TINYINT(1) DEFAULT 0 COMMENT '0-待分配 1-已分配 2-进行中 3-已完成', product_type VARCHAR(100), batch_size INT(11) COMMENT '批次大小', deadline DATE, assigned_to INT(11), assigned_at DATETIME, completed_at DATETIME, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_status (status), KEY idx_priority (priority), KEY idx_assigned_to (assigned_to) ) $charset_collate;"; // 派工记录表 $table_assignments = $wpdb->prefix . 'spa_assignments'; $sql_assignments = "CREATE TABLE IF NOT EXISTS $table_assignments ( id INT(11) NOT NULL AUTO_INCREMENT, task_id INT(11) NOT NULL, employee_id INT(11) NOT NULL, assigned_by INT(11) COMMENT '分配人用户ID', assignment_type TINYINT(1) DEFAULT 1 COMMENT '1-自动 2-手动', assignment_score FLOAT COMMENT '分配匹配度评分', notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_task_id (task_id), KEY idx_employee_id (employee_id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql_employees); dbDelta($sql_tasks); dbDelta($sql_assignments); }
- 核心的智能派工算法根据多个因素计算最佳匹配: class TaskAssignmentAlgorithm { /** * 智能派工主函数 * @param int $task_id 任务ID * @return array 分配结果 */ public function intelligent_assignment($task_id) { global $wpdb; // 获取任务详情 $task = $this->get_task_details($task_id); if (!$task) { return array('success' => false, 'message' => '任务不存在'); } // 获取可用员工 $available_employees = $this->get_available_employees(); if (empty($available_employees)) { return array('success' => false, 'message' => '没有可用员工'); } // 计算每个员工的匹配分数 $employee_scores = array(); foreach ($available_employees as $employee) { $score = $this->calculate_match_score($task, $employee); $employee_scores[$employee['id']] = array( 'employee' => $employee, 'score' => $score ); } // 按分数排序 uasort($employee_scores, function($a, $b) { return $b['score'] <=> $a['score']; }); // 选择最佳员工 $best_match = reset($employee_scores); $best_employee_id = $best_match['employee']['id']; // 分配任务 $result = $this->assign_task_to_employee($task_id, $best_employee_id, $best_match['score']); return array( 'success' => true, 'employee_id' => $best_employee_id, 'employee_name' => $best_match['employee']['name'], 'match_score' => round($best_match['score'], 2), 'assignment_id' => $result['assignment_id'] ); } /** * 计算任务与员工的匹配分数 * @param array $task 任务数据 * @param array $employee 员工数据 * @return float 匹配分数(0-100) */ private function calculate_match_score($task, $employee) { $total_score = 0; $weights = array( 'skill' => 0.35, // 技能匹配权重 'workload' => 0.25, // 工作负荷权重 'specialization' => 0.20, // 专长匹配权重 'efficiency' => 0.20 // 效率权重 ); // 1. 技能匹配度 (0-35分) $skill_score = $this->calculate_skill_score($task['required_skill'], $employee['skill_level']); $total_score += $skill_score * $weights['skill']; // 2. 工作负荷评分 (0-25分) $workload_score = $this->calculate_workload_score($employee); $total_score += $workload_score * $weights['workload']; // 3. 专长匹配度 (0-20分) $specialization_score = $this->calculate_specialization_score($task, $employee); $total_score += $specialization_score * $weights['specialization']; // 4. 历史效率评分 (0-20分) $efficiency_score = $this->calculate_efficiency_score($employee['id']); $total_score += $efficiency_score * $weights['efficiency']; return $total_score; } /** * 计算技能匹配分数 */ private function calculate_skill_score($required_skill, $employee_skill) { if ($employee_skill >= $required_skill) { // 技能达标,计算超出部分的奖励 $base_score = 30; $bonus = min(5, ($employee_skill - $required_skill) * 2); return $base_score + $bonus; } else { // 技能不足,按比例扣分 $ratio = $employee_skill / $required_skill; return 30 * $ratio; } } /** * 计算工作负荷分数 */ private function calculate_workload_score($employee) { $workload_ratio = $employee['current_workload'] / $employee['max_daily_tasks']; if ($workload_ratio < 0.5) { return 25; // 工作负荷轻,满分 } elseif ($workload_ratio < 0.8) { return 20; // 工作负荷适中 } elseif ($workload_ratio < 1.0) { return 10; // 工作负荷较重 } else { return 0; // 工作负荷已满 } } /** * 计算专长匹配分数 */ private function calculate_specialization_score($task, $employee) { if (empty($employee['specialization']) || empty($task['product_type'])) { return 10; // 默认分数 } // 简单的关键词匹配 $employee_specializations = explode(',', $employee['specialization']); $task_type = strtolower($task['product_type']); foreach ($employee_specializations as $specialization) { if (strpos($task_type, strtolower(trim($specialization))) !== false) { return 20; // 完全匹配 } } return 10; // 不匹配 } /** * 计算效率分数(基于历史完成时间) */ private function calculate_efficiency_score($employee_id) { global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; // 获取员工最近完成的任务 $query = $wpdb->prepare( "SELECT estimated_time, TIMESTAMPDIFF(MINUTE, assigned_at, completed_at) as actual_time FROM $table_tasks WHERE assigned_to = %d AND status = 3 AND estimated_time IS NOT NULL ORDER BY completed_at DESC LIMIT 10", $employee_id ); $results = $wpdb->get_results($query, ARRAY_A); if (empty($results)) { return 15; // 默认分数,没有历史数据 } $total_efficiency = 0; $count = 0; foreach ($results as $task) { if ($task['actual_time'] > 0) { $efficiency = $task['estimated_time'] / $task['actual_time']; $total_efficiency += min(1.5, max(0.5, $efficiency)); // 限制范围 $count++; } } if ($count > 0) { $avg_efficiency = $total_efficiency / $count; // 将效率转换为分数 (0.5-1.5 映射到 0-20分) return ($avg_efficiency - 0.5) * 20; } return 15; } /** * 获取可用员工列表 */ private function get_available_employees() { global $wpdb; $table_employees = $wpdb->prefix . 'spa_employees'; $query = "SELECT * FROM $table_employees WHERE is_active = 1 AND current_workload < max_daily_tasks ORDER BY current_workload ASC"; return $wpdb->get_results($query, ARRAY_A); } /** * 执行任务分配 */ private function assign_task_to_employee($task_id, $employee_id, $match_score) { global $wpdb; $wpdb->query('START TRANSACTION'); try { // 更新任务状态 $table_tasks = $wpdb->prefix . 'spa_tasks'; $wpdb->update( $table_tasks, array( 'status' => 1, 'assigned_to' => $employee_id, 'assigned_at' => current_time('mysql') ), array('id' => $task_id), array('%d', '%d', '%s'), array('%d') ); // 创建分配记录 $table_assignments = $wpdb->prefix . 'spa_assignments'; $wpdb->insert( $table_assignments, array( 'task_id' => $task_id, 'employee_id' => $employee_id, 'assigned_by' => get_current_user_id(), 'assignment_type' => 1, 'assignment_score' => $match_score, 'notes' => '系统智能分配' ), array('%d', '%d', '%d', '%d', '%f', '%s') ); $assignment_id = $wpdb->insert_id; // 更新员工工作量 $table_employees = $wpdb->prefix . 'spa_employees'; $wpdb->query( $wpdb->prepare( "UPDATE $table_employees SET current_workload = current_workload + 1 WHERE id = %d", $employee_id ) ); $wpdb->query('COMMIT'); return array('success' => true, 'assignment_id' => $assignment_id); } catch (Exception $e) { $wpdb->query('ROLLBACK'); return array('success' => false, 'error' => $e->getMessage()); } } }
- 创建用户友好的管理界面来管理任务和查看派工情况: // 在Smart_Production_Assignment类中添加 public function add_admin_menu() { // 主菜单 add_menu_page( '智能生产派工', '生产派工', 'manage_options', 'smart-production', array($this, 'render_main_page'), 'dashicons-clipboard', 30 ); // 子菜单 add_submenu_page( 'smart-production', '生产任务', '任务管理', 'manage_options', 'spa-tasks', array($this, 'render_tasks_page') ); add_submenu_page( 'smart-production', '员工管理', '员工管理', 'manage_options', 'spa-employees', array($this, 'render_employees_page') ); add_submenu_page( 'smart-production', '派工记录', '派工记录', 'manage_options', 'spa-assignments', array($this, 'render_assignments_page') ); add_submenu_page( 'smart-production', '批量派工', '批量派工', 'manage_options', 'spa-batch-assign', array($this, 'render_batch_assign_page') ); } /** * 渲染批量派工页面 */ public function render_batch_assign_page() { ?> <div class="wrap"> <h1>批量智能派工</h1> <div class="card"> <h2>待分配任务列表</h2> <?php global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; $pending_tasks = $wpdb->get_results( "SELECT * FROM $table_tasks WHERE status = 0 ORDER BY priority ASC, deadline ASC", ARRAY_A ); if (empty($pending_tasks)) { echo '<p>没有待分配的任务。</p>'; } else { echo '<table class="wp-list-table widefat fixed striped">'; echo '<thead> <tr> <th>任务名称</th> <th>优先级</th> <th>所需技能</th> <th>预计耗时</th> <th>截止日期</th> <th>操作</th> </tr> </thead>'; echo '<tbody>'; foreach ($pending_tasks as $task) { $priority_text = $this->get_priority_text($task['priority']); $priority_class = $this->get_priority_class($task['priority']); echo '<tr>'; echo '<td>' . esc_html($task['task_name']) . '</td>'; echo '<td><span class="' . $priority_class . '">' . $priority_text . '</span></td>'; echo '<td>等级 ' . esc_html($task['required_skill']) . '</td>'; echo '<td>' . esc_html($task['estimated_time']) . ' 分钟</td>'; echo '<td>' . esc_html($task['deadline']) . '</td>'; echo '<td> <button class="button button-small assign-single" data-task-id="' . esc_attr($task['id']) . '"> 智能分配 </button> </td>'; echo '</tr>'; } echo '</tbody></table>'; // 批量分配按钮 echo '<div style="margin-top: 20px;"> <button id="batch-assign-all" class="button button-primary"> 智能分配所有待分配任务 </button> <span id="batch-progress" style="margin-left: 15px; display: none;"></span> </div>'; } ?> </div> <div class="card" style="margin-top: 20px;"> <h2>实时分配结果</h2> <div id="assignment-results"> <!-- 分配结果将通过AJAX动态显示 --> </div> </div> </div> <script> jQuery(document).ready(function($) { // 单个任务分配 $('.assign-single').on('click', function() { var taskId = $(this).data('task-id'); var button = $(this); button.prop('disabled', true).text('分配中...'); $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'spa_assign_task', task_id: taskId, nonce: '<?php echo wp_create_nonce("spa_assign_nonce"); ?>' }, success: function(response) { if (response.success) { $('#assignment-results').prepend( '<div class="notice notice-success"><p>' + '任务已分配给 ' + response.employee_name + ' (匹配度: ' + response.match_score + '%)</p></div>' ); button.closest('tr').fadeOut(); } else { $('#assignment-results').prepend( '<div class="notice notice-error"><p>' + response.message + '</p></div>' ); button.prop('disabled', false).text('智能分配'); } } }); }); // 批量分配所有任务 $('#batch-assign-all').on('click', function() { var button = $(this); var progress = $('#batch-progress'); button.prop('disabled', true); progress.show().text('开始分配...'); // 获取所有待分配任务ID var taskIds = []; $('.assign-single').each(function() { taskIds.push($(this).data('task-id')); }); if (taskIds.length === 0) { progress.text('没有待分配的任务'); return; } // 逐个分配任务 var completed = 0; var total = taskIds.length; function assignNextTask() { if (completed >= total) { progress.text('所有任务分配完成!'); button.prop('disabled', false); return; } var taskId = taskIds[completed]; progress.text('正在分配任务 ' + (completed + 1) + '/' + total); $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'spa_assign_task', task_id: taskId, nonce: '<?php echo wp_create_nonce("spa_assign_nonce"); ?>' }, success: function(response) { completed++; if (response.success) { $('#assignment-results').prepend( '<div class="notice notice-success"><p>' + '任务#' + taskId + ' 已分配给 ' + response.employee_name + ' (匹配度: ' + response.match_score + '%)</p></div>' ); $('[data-task-id="' + taskId + '"]').closest('tr').fadeOut(); } else { $('#assignment-results').prepend( '<div class="notice notice-error"><p>任务#' + taskId + ': ' + response.message + '</p></div>' ); } // 继续分配下一个任务 setTimeout(assignNextTask, 500); }, error: function() { completed++; $('#assignment-results').prepend( '<div class="notice notice-error"><p>任务#' + taskId + ': 分配失败</p></div>' ); setTimeout(assignNextTask, 500); } }); } assignNextTask(); }); }); </script> <?php } /** * 渲染任务管理页面 */ public function render_tasks_page() { // 处理表单提交 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_task'])) { $this->add_new_task($_POST); } ?> <div class="wrap"> <h1>生产任务管理</h1> <div class="card"> <h2>添加新任务</h2> <form method="POST" action=""> <table class="form-table"> <tr> <th><label for="task_name">任务名称</label></th> <td><input type="text" id="task_name" name="task_name" required class="regular-text"></td> </tr> <tr> <th><label for="description">任务描述</label></th> <td><textarea id="description" name="description" rows="3" class="large-text"></textarea></td> </tr> <tr> <th><label for="required_skill">所需技能等级</label></th> <td> <select id="required_skill" name="required_skill"> <?php for ($i = 1; $i <= 5; $i++): ?> <option value="<?php echo $i; ?>"><?php echo $i; ?> 级</option> <?php endfor; ?> </select> </td> </tr> <tr> <th><label for="estimated_time">预计耗时(分钟)</label></th> <td><input type="number" id="estimated_time" name="estimated_time" min="1" required></td> </tr> <tr> <th><label for="priority">优先级</label></th> <td> <select id="priority" name="priority"> <option value="1">高</option> <option value="2" selected>中</option> <option value="3">低</option> </select> </td> </tr> <tr> <th><label for="product_type">产品类型</label></th> <td><input type="text" id="product_type" name="product_type" class="regular-text"></td> </tr> <tr> <th><label for="batch_size">批次大小</label></th> <td><input type="number" id="batch_size" name="batch_size" min="1" value="1"></td> </tr> <tr> <th><label for="deadline">截止日期</label></th> <td><input type="date" id="deadline" name="deadline" required></td> </tr> </table> <?php submit_button('添加任务', 'primary', 'add_task'); ?> </form> </div> <div class="card" style="margin-top: 20px;"> <h2>任务列表</h2> <?php global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; $table_employees = $wpdb->prefix . 'spa_employees'; $tasks = $wpdb->get_results(" SELECT t.*, e.name as assigned_employee FROM $table_tasks t LEFT JOIN $table_employees e ON t.assigned_to = e.id ORDER BY t.priority ASC, t.deadline ASC ", ARRAY_A); if ($tasks) { echo '<table class="wp-list-table widefat fixed striped">'; echo '<thead> <tr> <th>ID</th> <th>任务名称</th> <th>优先级</th> <th>状态</th> <th>分配员工</th> <th>截止日期</th> <th>操作</th> </tr> </thead>'; echo '<tbody>'; foreach ($tasks as $task) { $status_text = $this->get_status_text($task['status']); $status_class = $this->get_status_class($task['status']); $priority_text = $this->get_priority_text($task['priority']); echo '<tr>'; echo '<td>' . esc_html($task['id']) . '</td>'; echo '<td>' . esc_html($task['task_name']) . '</td>'; echo '<td>' . esc_html($priority_text) . '</td>'; echo '<td><span class="' . esc_attr($status_class) . '">' . esc_html($status_text) . '</span></td>'; echo '<td>' . esc_html($task['assigned_employee'] ?: '未分配') . '</td>'; echo '<td>' . esc_html($task['deadline']) . '</td>'; echo '<td> <a href="?page=spa-tasks&action=edit&id=' . esc_attr($task['id']) . '" class="button button-small">编辑</a> <a href="?page=spa-tasks&action=delete&id=' . esc_attr($task['id']) . '" class="button button-small button-danger" onclick="return confirm('确定删除此任务?')">删除</a> </td>'; echo '</tr>'; } echo '</tbody></table>'; } else { echo '<p>暂无任务。</p>'; } ?> </div> </div> <?php } /** * 添加新任务 */ private function add_new_task($data) { global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; $result = $wpdb->insert( $table_tasks, array( 'task_name' => sanitize_text_field($data['task_name']), 'description' => sanitize_textarea_field($data['description']), 'required_skill' => intval($data['required_skill']), 'estimated_time' => intval($data['estimated_time']), 'priority' => intval($data['priority']), 'product_type' => sanitize_text_field($data['product_type']), 'batch_size' => intval($data['batch_size']), 'deadline' => sanitize_text_field($data['deadline']), 'status' => 0 ), array('%s', '%s', '%d', '%d', '%d', '%s', '%d', '%s', '%d') ); if ($result) { echo '<div class="notice notice-success"><p>任务添加成功!</p></div>'; } else { echo '<div class="notice notice-error"><p>任务添加失败。</p></div>'; } }
- // 在init_hooks方法中添加AJAX处理 add_action('wp_ajax_spa_assign_task', array($this, 'ajax_assign_task')); add_action('wp_ajax_spa_get_task_stats', array($this, 'ajax_get_task_stats')); add_action('wp_ajax_spa_update_task_status', array($this, 'ajax_update_task_status')); /** * AJAX处理任务分配 */ public function ajax_assign_task() { // 验证nonce if (!wp_verify_nonce($_POST['nonce'], 'spa_assign_nonce')) { wp_die('安全验证失败'); } $task_id = intval($_POST['task_id']); // 调用智能派工算法 $algorithm = new TaskAssignmentAlgorithm(); $result = $algorithm->intelligent_assignment($task_id); wp_send_json($result); } /** * 获取任务统计信息 */ public function ajax_get_task_stats() { global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; $stats = array( 'total' => 0, 'pending' => 0, 'assigned' => 0, 'in_progress' => 0, 'completed' => 0 ); // 获取总数 $stats['total'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_tasks"); // 按状态统计 $status_counts = $wpdb->get_results(" SELECT status, COUNT(*) as count FROM $table_tasks GROUP BY status ", ARRAY_A); foreach ($status_counts as $row) { switch ($row['status']) { case 0: $stats['pending'] = $row['count']; break; case 1: $stats['assigned'] = $row['count']; break; case 2: $stats['in_progress'] = $row['count']; break; case 3: $stats['completed'] = $row['count']; break; } } wp_send_json($stats); } /** * 更新任务状态 */ public function ajax_update_task_status() { global $wpdb; $task_id = intval($_POST['task_id']); $status = intval($_POST['status']); $table_tasks = $wpdb->prefix . 'spa_tasks'; $data = array('status' => $status); if ($status == 3) { // 完成状态 $data['completed_at'] = current_time('mysql'); // 减少员工工作量 $task = $wpdb->get_row( $wpdb->prepare("SELECT assigned_to FROM $table_tasks WHERE id = %d", $task_id), ARRAY_A ); if ($task && $task['assigned_to']) { $table_employees = $wpdb->prefix . 'spa_employees'; $wpdb->query( $wpdb->prepare( "UPDATE $table_employees SET current_workload = GREATEST(0, current_workload - 1) WHERE id = %d", $task['assigned_to'] ) ); } } $result = $wpdb->update( $table_tasks, $data, array('id' => $task_id), $status == 3 ? array('%d', '%s') : array('%d'), array('%d') ); wp_send_json(array('success' => $result !== false)); }
- // 添加仪表板小工具 add_action('wp_dashboard_setup', array($this, 'add_dashboard_widgets')); public function add_dashboard_widgets() { wp_add_dashboard_widget( 'spa_task_overview', '生产任务概览', array($this, 'render_dashboard_widget') ); } public function render_dashboard_widget() { global $wpdb; $table_tasks = $wpdb->prefix . 'spa_tasks'; $table_employees = $wpdb->prefix . 'spa_employees'; // 获取紧急任务 $urgent_tasks = $wpdb->get_results(" SELECT * FROM $table_tasks WHERE status IN (0, 1, 2) AND deadline <= DATE_ADD(CURDATE(), INTERVAL 3 DAY) ORDER BY deadline ASC LIMIT 5 ", ARRAY_A); // 获取员工负荷情况 $employee_load = $wpdb->get_results(" SELECT name, current_workload, max_daily_tasks, ROUND((current_workload / max_daily_tasks) * 100) as load_percentage FROM $table_employees WHERE is_active = 1 ORDER BY load_percentage DESC ", ARRAY_A); echo '<h3>即将到期的任务</h3>'; if ($urgent_tasks) { echo '<ul>'; foreach ($urgent_tasks as $task) { $days_left = ceil((strtotime($task['deadline']) - time()) / (60 * 60 * 24)); $status_class = $this->get_status_class($task['status']); $status_text = $this->get_status_text($task['status']); echo '<li>'; echo '<strong>' . esc_html($task['task_name']) . '</strong><br>'; echo '截止: ' . esc_html($task['deadline']) . ' (' . $days_left . '天)'; echo ' | 状态: <span class="' . $status_class . '">' . $status_text . '</span>'; echo '</li>'; } echo '</ul>'; } else { echo '<p>没有即将到期的任务。</p>'; } echo '<h3>员工工作负荷</h3>'; echo '<table style="width: 100%;">'; foreach ($employee_load as $employee) { $percentage = $employee['load_percentage']; $bar_color = $percentage < 60 ? 'green' : ($percentage < 85 ? 'orange' : 'red'); echo '<tr>'; echo '<td>' . esc_html($employee['name']) . '</td>'; echo '<td style="width: 60%; padding: 0 10px;">';
在现代生产制造企业中,任务派工是生产管理的核心环节。本教程将指导您开发一个WordPress定制插件,实现小批量生产任务的智能派工系统。该系统能够根据员工技能、工作负荷和任务优先级自动分配生产任务,提高生产效率。
首先,我们需要创建插件的基本文件结构:
<?php
/**
* Plugin Name: 智能生产任务派工系统
* Plugin URI: https://yourwebsite.com/
* Description: 小批量生产任务智能派工解决方案
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('SPA_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('SPA_PLUGIN_URL', plugin_dir_url(__FILE__));
define('SPA_VERSION', '1.0.0');
// 初始化插件
class Smart_Production_Assignment {
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_plugin'));
register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin'));
// 初始化
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_plugin() {
$this->create_tables();
$this->insert_default_data();
}
public function deactivate_plugin() {
// 清理临时数据(可选)
}
public function init() {
// 初始化代码
}
// 其他方法将在下面逐步实现
}
// 启动插件
Smart_Production_Assignment::get_instance();
?>
智能派工系统需要存储员工信息、任务数据和派工记录:
// 在activate_plugin方法中调用
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 员工技能表
$table_employees = $wpdb->prefix . 'spa_employees';
$sql_employees = "CREATE TABLE IF NOT EXISTS $table_employees (
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
skill_level TINYINT(3) DEFAULT 1 COMMENT '技能等级 1-5',
current_workload INT(11) DEFAULT 0 COMMENT '当前工作量',
max_daily_tasks INT(11) DEFAULT 5 COMMENT '每日最大任务数',
specialization VARCHAR(100) COMMENT '专长领域',
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 生产任务表
$table_tasks = $wpdb->prefix . 'spa_tasks';
$sql_tasks = "CREATE TABLE IF NOT EXISTS $table_tasks (
id INT(11) NOT NULL AUTO_INCREMENT,
task_name VARCHAR(200) NOT NULL,
description TEXT,
required_skill TINYINT(3) DEFAULT 1 COMMENT '所需技能等级',
estimated_time INT(11) COMMENT '预计耗时(分钟)',
priority TINYINT(2) DEFAULT 2 COMMENT '优先级 1-高 2-中 3-低',
status TINYINT(1) DEFAULT 0 COMMENT '0-待分配 1-已分配 2-进行中 3-已完成',
product_type VARCHAR(100),
batch_size INT(11) COMMENT '批次大小',
deadline DATE,
assigned_to INT(11),
assigned_at DATETIME,
completed_at DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_status (status),
KEY idx_priority (priority),
KEY idx_assigned_to (assigned_to)
) $charset_collate;";
// 派工记录表
$table_assignments = $wpdb->prefix . 'spa_assignments';
$sql_assignments = "CREATE TABLE IF NOT EXISTS $table_assignments (
id INT(11) NOT NULL AUTO_INCREMENT,
task_id INT(11) NOT NULL,
employee_id INT(11) NOT NULL,
assigned_by INT(11) COMMENT '分配人用户ID',
assignment_type TINYINT(1) DEFAULT 1 COMMENT '1-自动 2-手动',
assignment_score FLOAT COMMENT '分配匹配度评分',
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_task_id (task_id),
KEY idx_employee_id (employee_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_employees);
dbDelta($sql_tasks);
dbDelta($sql_assignments);
}
核心的智能派工算法根据多个因素计算最佳匹配:
class TaskAssignmentAlgorithm {
/**
* 智能派工主函数
* @param int $task_id 任务ID
* @return array 分配结果
*/
public function intelligent_assignment($task_id) {
global $wpdb;
// 获取任务详情
$task = $this->get_task_details($task_id);
if (!$task) {
return array('success' => false, 'message' => '任务不存在');
}
// 获取可用员工
$available_employees = $this->get_available_employees();
if (empty($available_employees)) {
return array('success' => false, 'message' => '没有可用员工');
}
// 计算每个员工的匹配分数
$employee_scores = array();
foreach ($available_employees as $employee) {
$score = $this->calculate_match_score($task, $employee);
$employee_scores[$employee['id']] = array(
'employee' => $employee,
'score' => $score
);
}
// 按分数排序
uasort($employee_scores, function($a, $b) {
return $b['score'] <=> $a['score'];
});
// 选择最佳员工
$best_match = reset($employee_scores);
$best_employee_id = $best_match['employee']['id'];
// 分配任务
$result = $this->assign_task_to_employee($task_id, $best_employee_id, $best_match['score']);
return array(
'success' => true,
'employee_id' => $best_employee_id,
'employee_name' => $best_match['employee']['name'],
'match_score' => round($best_match['score'], 2),
'assignment_id' => $result['assignment_id']
);
}
/**
* 计算任务与员工的匹配分数
* @param array $task 任务数据
* @param array $employee 员工数据
* @return float 匹配分数(0-100)
*/
private function calculate_match_score($task, $employee) {
$total_score = 0;
$weights = array(
'skill' => 0.35, // 技能匹配权重
'workload' => 0.25, // 工作负荷权重
'specialization' => 0.20, // 专长匹配权重
'efficiency' => 0.20 // 效率权重
);
// 1. 技能匹配度 (0-35分)
$skill_score = $this->calculate_skill_score($task['required_skill'], $employee['skill_level']);
$total_score += $skill_score * $weights['skill'];
// 2. 工作负荷评分 (0-25分)
$workload_score = $this->calculate_workload_score($employee);
$total_score += $workload_score * $weights['workload'];
// 3. 专长匹配度 (0-20分)
$specialization_score = $this->calculate_specialization_score($task, $employee);
$total_score += $specialization_score * $weights['specialization'];
// 4. 历史效率评分 (0-20分)
$efficiency_score = $this->calculate_efficiency_score($employee['id']);
$total_score += $efficiency_score * $weights['efficiency'];
return $total_score;
}
/**
* 计算技能匹配分数
*/
private function calculate_skill_score($required_skill, $employee_skill) {
if ($employee_skill >= $required_skill) {
// 技能达标,计算超出部分的奖励
$base_score = 30;
$bonus = min(5, ($employee_skill - $required_skill) * 2);
return $base_score + $bonus;
} else {
// 技能不足,按比例扣分
$ratio = $employee_skill / $required_skill;
return 30 * $ratio;
}
}
/**
* 计算工作负荷分数
*/
private function calculate_workload_score($employee) {
$workload_ratio = $employee['current_workload'] / $employee['max_daily_tasks'];
if ($workload_ratio < 0.5) {
return 25; // 工作负荷轻,满分
} elseif ($workload_ratio < 0.8) {
return 20; // 工作负荷适中
} elseif ($workload_ratio < 1.0) {
return 10; // 工作负荷较重
} else {
return 0; // 工作负荷已满
}
}
/**
* 计算专长匹配分数
*/
private function calculate_specialization_score($task, $employee) {
if (empty($employee['specialization']) || empty($task['product_type'])) {
return 10; // 默认分数
}
// 简单的关键词匹配
$employee_specializations = explode(',', $employee['specialization']);
$task_type = strtolower($task['product_type']);
foreach ($employee_specializations as $specialization) {
if (strpos($task_type, strtolower(trim($specialization))) !== false) {
return 20; // 完全匹配
}
}
return 10; // 不匹配
}
/**
* 计算效率分数(基于历史完成时间)
*/
private function calculate_efficiency_score($employee_id) {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
// 获取员工最近完成的任务
$query = $wpdb->prepare(
"SELECT estimated_time,
TIMESTAMPDIFF(MINUTE, assigned_at, completed_at) as actual_time
FROM $table_tasks
WHERE assigned_to = %d
AND status = 3
AND estimated_time IS NOT NULL
ORDER BY completed_at DESC
LIMIT 10",
$employee_id
);
$results = $wpdb->get_results($query, ARRAY_A);
if (empty($results)) {
return 15; // 默认分数,没有历史数据
}
$total_efficiency = 0;
$count = 0;
foreach ($results as $task) {
if ($task['actual_time'] > 0) {
$efficiency = $task['estimated_time'] / $task['actual_time'];
$total_efficiency += min(1.5, max(0.5, $efficiency)); // 限制范围
$count++;
}
}
if ($count > 0) {
$avg_efficiency = $total_efficiency / $count;
// 将效率转换为分数 (0.5-1.5 映射到 0-20分)
return ($avg_efficiency - 0.5) * 20;
}
return 15;
}
/**
* 获取可用员工列表
*/
private function get_available_employees() {
global $wpdb;
$table_employees = $wpdb->prefix . 'spa_employees';
$query = "SELECT * FROM $table_employees
WHERE is_active = 1
AND current_workload < max_daily_tasks
ORDER BY current_workload ASC";
return $wpdb->get_results($query, ARRAY_A);
}
/**
* 执行任务分配
*/
private function assign_task_to_employee($task_id, $employee_id, $match_score) {
global $wpdb;
$wpdb->query('START TRANSACTION');
try {
// 更新任务状态
$table_tasks = $wpdb->prefix . 'spa_tasks';
$wpdb->update(
$table_tasks,
array(
'status' => 1,
'assigned_to' => $employee_id,
'assigned_at' => current_time('mysql')
),
array('id' => $task_id),
array('%d', '%d', '%s'),
array('%d')
);
// 创建分配记录
$table_assignments = $wpdb->prefix . 'spa_assignments';
$wpdb->insert(
$table_assignments,
array(
'task_id' => $task_id,
'employee_id' => $employee_id,
'assigned_by' => get_current_user_id(),
'assignment_type' => 1,
'assignment_score' => $match_score,
'notes' => '系统智能分配'
),
array('%d', '%d', '%d', '%d', '%f', '%s')
);
$assignment_id = $wpdb->insert_id;
// 更新员工工作量
$table_employees = $wpdb->prefix . 'spa_employees';
$wpdb->query(
$wpdb->prepare(
"UPDATE $table_employees
SET current_workload = current_workload + 1
WHERE id = %d",
$employee_id
)
);
$wpdb->query('COMMIT');
return array('success' => true, 'assignment_id' => $assignment_id);
} catch (Exception $e) {
$wpdb->query('ROLLBACK');
return array('success' => false, 'error' => $e->getMessage());
}
}
}
创建用户友好的管理界面来管理任务和查看派工情况:
// 在Smart_Production_Assignment类中添加
public function add_admin_menu() {
// 主菜单
add_menu_page(
'智能生产派工',
'生产派工',
'manage_options',
'smart-production',
array($this, 'render_main_page'),
'dashicons-clipboard',
30
);
// 子菜单
add_submenu_page(
'smart-production',
'生产任务',
'任务管理',
'manage_options',
'spa-tasks',
array($this, 'render_tasks_page')
);
add_submenu_page(
'smart-production',
'员工管理',
'员工管理',
'manage_options',
'spa-employees',
array($this, 'render_employees_page')
);
add_submenu_page(
'smart-production',
'派工记录',
'派工记录',
'manage_options',
'spa-assignments',
array($this, 'render_assignments_page')
);
add_submenu_page(
'smart-production',
'批量派工',
'批量派工',
'manage_options',
'spa-batch-assign',
array($this, 'render_batch_assign_page')
);
}
/**
* 渲染批量派工页面
*/
public function render_batch_assign_page() {
?>
<div class="wrap">
<h1>批量智能派工</h1>
<div class="card">
<h2>待分配任务列表</h2>
<?php
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$pending_tasks = $wpdb->get_results(
"SELECT * FROM $table_tasks WHERE status = 0 ORDER BY priority ASC, deadline ASC",
ARRAY_A
);
if (empty($pending_tasks)) {
echo '<p>没有待分配的任务。</p>';
} else {
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead>
<tr>
<th>任务名称</th>
<th>优先级</th>
<th>所需技能</th>
<th>预计耗时</th>
<th>截止日期</th>
<th>操作</th>
</tr>
</thead>';
echo '<tbody>';
foreach ($pending_tasks as $task) {
$priority_text = $this->get_priority_text($task['priority']);
$priority_class = $this->get_priority_class($task['priority']);
echo '<tr>';
echo '<td>' . esc_html($task['task_name']) . '</td>';
echo '<td><span class="' . $priority_class . '">' . $priority_text . '</span></td>';
echo '<td>等级 ' . esc_html($task['required_skill']) . '</td>';
echo '<td>' . esc_html($task['estimated_time']) . ' 分钟</td>';
echo '<td>' . esc_html($task['deadline']) . '</td>';
echo '<td>
<button class="button button-small assign-single" data-task-id="' . esc_attr($task['id']) . '">
智能分配
</button>
</td>';
echo '</tr>';
}
echo '</tbody></table>';
// 批量分配按钮
echo '<div style="margin-top: 20px;">
<button id="batch-assign-all" class="button button-primary">
智能分配所有待分配任务
</button>
<span id="batch-progress" style="margin-left: 15px; display: none;"></span>
</div>';
}
?>
</div>
<div class="card" style="margin-top: 20px;">
<h2>实时分配结果</h2>
<div id="assignment-results">
<!-- 分配结果将通过AJAX动态显示 -->
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
// 单个任务分配
$('.assign-single').on('click', function() {
var taskId = $(this).data('task-id');
var button = $(this);
button.prop('disabled', true).text('分配中...');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'spa_assign_task',
task_id: taskId,
nonce: '<?php echo wp_create_nonce("spa_assign_nonce"); ?>'
},
success: function(response) {
if (response.success) {
$('#assignment-results').prepend(
'<div class="notice notice-success"><p>' +
'任务已分配给 ' + response.employee_name +
' (匹配度: ' + response.match_score + '%)</p></div>'
);
button.closest('tr').fadeOut();
} else {
$('#assignment-results').prepend(
'<div class="notice notice-error"><p>' + response.message + '</p></div>'
);
button.prop('disabled', false).text('智能分配');
}
}
});
});
// 批量分配所有任务
$('#batch-assign-all').on('click', function() {
var button = $(this);
var progress = $('#batch-progress');
button.prop('disabled', true);
progress.show().text('开始分配...');
// 获取所有待分配任务ID
var taskIds = [];
$('.assign-single').each(function() {
taskIds.push($(this).data('task-id'));
});
if (taskIds.length === 0) {
progress.text('没有待分配的任务');
return;
}
// 逐个分配任务
var completed = 0;
var total = taskIds.length;
function assignNextTask() {
if (completed >= total) {
progress.text('所有任务分配完成!');
button.prop('disabled', false);
return;
}
var taskId = taskIds[completed];
progress.text('正在分配任务 ' + (completed + 1) + '/' + total);
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'spa_assign_task',
task_id: taskId,
nonce: '<?php echo wp_create_nonce("spa_assign_nonce"); ?>'
},
success: function(response) {
completed++;
if (response.success) {
$('#assignment-results').prepend(
'<div class="notice notice-success"><p>' +
'任务#' + taskId + ' 已分配给 ' + response.employee_name +
' (匹配度: ' + response.match_score + '%)</p></div>'
);
$('[data-task-id="' + taskId + '"]').closest('tr').fadeOut();
} else {
$('#assignment-results').prepend(
'<div class="notice notice-error"><p>任务#' + taskId + ': ' + response.message + '</p></div>'
);
}
// 继续分配下一个任务
setTimeout(assignNextTask, 500);
},
error: function() {
completed++;
$('#assignment-results').prepend(
'<div class="notice notice-error"><p>任务#' + taskId + ': 分配失败</p></div>'
);
setTimeout(assignNextTask, 500);
}
});
}
assignNextTask();
});
});
</script>
<?php
}
/**
* 渲染任务管理页面
*/
public function render_tasks_page() {
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_task'])) {
$this->add_new_task($_POST);
}
?>
<div class="wrap">
<h1>生产任务管理</h1>
<div class="card">
<h2>添加新任务</h2>
<form method="POST" action="">
<table class="form-table">
<tr>
<th><label for="task_name">任务名称</label></th>
<td><input type="text" id="task_name" name="task_name" required class="regular-text"></td>
</tr>
<tr>
<th><label for="description">任务描述</label></th>
<td><textarea id="description" name="description" rows="3" class="large-text"></textarea></td>
</tr>
<tr>
<th><label for="required_skill">所需技能等级</label></th>
<td>
<select id="required_skill" name="required_skill">
<?php for ($i = 1; $i <= 5; $i++): ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?> 级</option>
<?php endfor; ?>
</select>
</td>
</tr>
<tr>
<th><label for="estimated_time">预计耗时(分钟)</label></th>
<td><input type="number" id="estimated_time" name="estimated_time" min="1" required></td>
</tr>
<tr>
<th><label for="priority">优先级</label></th>
<td>
<select id="priority" name="priority">
<option value="1">高</option>
<option value="2" selected>中</option>
<option value="3">低</option>
</select>
</td>
</tr>
<tr>
<th><label for="product_type">产品类型</label></th>
<td><input type="text" id="product_type" name="product_type" class="regular-text"></td>
</tr>
<tr>
<th><label for="batch_size">批次大小</label></th>
<td><input type="number" id="batch_size" name="batch_size" min="1" value="1"></td>
</tr>
<tr>
<th><label for="deadline">截止日期</label></th>
<td><input type="date" id="deadline" name="deadline" required></td>
</tr>
</table>
<?php submit_button('添加任务', 'primary', 'add_task'); ?>
</form>
</div>
<div class="card" style="margin-top: 20px;">
<h2>任务列表</h2>
<?php
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$table_employees = $wpdb->prefix . 'spa_employees';
$tasks = $wpdb->get_results("
SELECT t.*, e.name as assigned_employee
FROM $table_tasks t
LEFT JOIN $table_employees e ON t.assigned_to = e.id
ORDER BY t.priority ASC, t.deadline ASC
", ARRAY_A);
if ($tasks) {
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead>
<tr>
<th>ID</th>
<th>任务名称</th>
<th>优先级</th>
<th>状态</th>
<th>分配员工</th>
<th>截止日期</th>
<th>操作</th>
</tr>
</thead>';
echo '<tbody>';
foreach ($tasks as $task) {
$status_text = $this->get_status_text($task['status']);
$status_class = $this->get_status_class($task['status']);
$priority_text = $this->get_priority_text($task['priority']);
echo '<tr>';
echo '<td>' . esc_html($task['id']) . '</td>';
echo '<td>' . esc_html($task['task_name']) . '</td>';
echo '<td>' . esc_html($priority_text) . '</td>';
echo '<td><span class="' . esc_attr($status_class) . '">' . esc_html($status_text) . '</span></td>';
echo '<td>' . esc_html($task['assigned_employee'] ?: '未分配') . '</td>';
echo '<td>' . esc_html($task['deadline']) . '</td>';
echo '<td>
<a href="?page=spa-tasks&action=edit&id=' . esc_attr($task['id']) . '" class="button button-small">编辑</a>
<a href="?page=spa-tasks&action=delete&id=' . esc_attr($task['id']) . '"
class="button button-small button-danger"
onclick="return confirm('确定删除此任务?')">删除</a>
</td>';
echo '</tr>';
}
echo '</tbody></table>';
} else {
echo '<p>暂无任务。</p>';
}
?>
</div>
</div>
<?php
}
/**
* 添加新任务
*/
private function add_new_task($data) {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$result = $wpdb->insert(
$table_tasks,
array(
'task_name' => sanitize_text_field($data['task_name']),
'description' => sanitize_textarea_field($data['description']),
'required_skill' => intval($data['required_skill']),
'estimated_time' => intval($data['estimated_time']),
'priority' => intval($data['priority']),
'product_type' => sanitize_text_field($data['product_type']),
'batch_size' => intval($data['batch_size']),
'deadline' => sanitize_text_field($data['deadline']),
'status' => 0
),
array('%s', '%s', '%d', '%d', '%d', '%s', '%d', '%s', '%d')
);
if ($result) {
echo '<div class="notice notice-success"><p>任务添加成功!</p></div>';
} else {
echo '<div class="notice notice-error"><p>任务添加失败。</p></div>';
}
}
// 在init_hooks方法中添加AJAX处理
add_action('wp_ajax_spa_assign_task', array($this, 'ajax_assign_task'));
add_action('wp_ajax_spa_get_task_stats', array($this, 'ajax_get_task_stats'));
add_action('wp_ajax_spa_update_task_status', array($this, 'ajax_update_task_status'));
/**
* AJAX处理任务分配
*/
public function ajax_assign_task() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'spa_assign_nonce')) {
wp_die('安全验证失败');
}
$task_id = intval($_POST['task_id']);
// 调用智能派工算法
$algorithm = new TaskAssignmentAlgorithm();
$result = $algorithm->intelligent_assignment($task_id);
wp_send_json($result);
}
/**
* 获取任务统计信息
*/
public function ajax_get_task_stats() {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$stats = array(
'total' => 0,
'pending' => 0,
'assigned' => 0,
'in_progress' => 0,
'completed' => 0
);
// 获取总数
$stats['total'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_tasks");
// 按状态统计
$status_counts = $wpdb->get_results("
SELECT status, COUNT(*) as count
FROM $table_tasks
GROUP BY status
", ARRAY_A);
foreach ($status_counts as $row) {
switch ($row['status']) {
case 0: $stats['pending'] = $row['count']; break;
case 1: $stats['assigned'] = $row['count']; break;
case 2: $stats['in_progress'] = $row['count']; break;
case 3: $stats['completed'] = $row['count']; break;
}
}
wp_send_json($stats);
}
/**
* 更新任务状态
*/
public function ajax_update_task_status() {
global $wpdb;
$task_id = intval($_POST['task_id']);
$status = intval($_POST['status']);
$table_tasks = $wpdb->prefix . 'spa_tasks';
$data = array('status' => $status);
if ($status == 3) { // 完成状态
$data['completed_at'] = current_time('mysql');
// 减少员工工作量
$task = $wpdb->get_row(
$wpdb->prepare("SELECT assigned_to FROM $table_tasks WHERE id = %d", $task_id),
ARRAY_A
);
if ($task && $task['assigned_to']) {
$table_employees = $wpdb->prefix . 'spa_employees';
$wpdb->query(
$wpdb->prepare(
"UPDATE $table_employees
SET current_workload = GREATEST(0, current_workload - 1)
WHERE id = %d",
$task['assigned_to']
)
);
}
}
$result = $wpdb->update(
$table_tasks,
$data,
array('id' => $task_id),
$status == 3 ? array('%d', '%s') : array('%d'),
array('%d')
);
wp_send_json(array('success' => $result !== false));
}
// 在init_hooks方法中添加AJAX处理
add_action('wp_ajax_spa_assign_task', array($this, 'ajax_assign_task'));
add_action('wp_ajax_spa_get_task_stats', array($this, 'ajax_get_task_stats'));
add_action('wp_ajax_spa_update_task_status', array($this, 'ajax_update_task_status'));
/**
* AJAX处理任务分配
*/
public function ajax_assign_task() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'spa_assign_nonce')) {
wp_die('安全验证失败');
}
$task_id = intval($_POST['task_id']);
// 调用智能派工算法
$algorithm = new TaskAssignmentAlgorithm();
$result = $algorithm->intelligent_assignment($task_id);
wp_send_json($result);
}
/**
* 获取任务统计信息
*/
public function ajax_get_task_stats() {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$stats = array(
'total' => 0,
'pending' => 0,
'assigned' => 0,
'in_progress' => 0,
'completed' => 0
);
// 获取总数
$stats['total'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_tasks");
// 按状态统计
$status_counts = $wpdb->get_results("
SELECT status, COUNT(*) as count
FROM $table_tasks
GROUP BY status
", ARRAY_A);
foreach ($status_counts as $row) {
switch ($row['status']) {
case 0: $stats['pending'] = $row['count']; break;
case 1: $stats['assigned'] = $row['count']; break;
case 2: $stats['in_progress'] = $row['count']; break;
case 3: $stats['completed'] = $row['count']; break;
}
}
wp_send_json($stats);
}
/**
* 更新任务状态
*/
public function ajax_update_task_status() {
global $wpdb;
$task_id = intval($_POST['task_id']);
$status = intval($_POST['status']);
$table_tasks = $wpdb->prefix . 'spa_tasks';
$data = array('status' => $status);
if ($status == 3) { // 完成状态
$data['completed_at'] = current_time('mysql');
// 减少员工工作量
$task = $wpdb->get_row(
$wpdb->prepare("SELECT assigned_to FROM $table_tasks WHERE id = %d", $task_id),
ARRAY_A
);
if ($task && $task['assigned_to']) {
$table_employees = $wpdb->prefix . 'spa_employees';
$wpdb->query(
$wpdb->prepare(
"UPDATE $table_employees
SET current_workload = GREATEST(0, current_workload - 1)
WHERE id = %d",
$task['assigned_to']
)
);
}
}
$result = $wpdb->update(
$table_tasks,
$data,
array('id' => $task_id),
$status == 3 ? array('%d', '%s') : array('%d'),
array('%d')
);
wp_send_json(array('success' => $result !== false));
}
// 添加仪表板小工具
add_action('wp_dashboard_setup', array($this, 'add_dashboard_widgets'));
public function add_dashboard_widgets() {
wp_add_dashboard_widget(
'spa_task_overview',
'生产任务概览',
array($this, 'render_dashboard_widget')
);
}
public function render_dashboard_widget() {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$table_employees = $wpdb->prefix . 'spa_employees';
// 获取紧急任务
$urgent_tasks = $wpdb->get_results("
SELECT * FROM $table_tasks
WHERE status IN (0, 1, 2)
AND deadline <= DATE_ADD(CURDATE(), INTERVAL 3 DAY)
ORDER BY deadline ASC
LIMIT 5
", ARRAY_A);
// 获取员工负荷情况
$employee_load = $wpdb->get_results("
SELECT name, current_workload, max_daily_tasks,
ROUND((current_workload / max_daily_tasks) * 100) as load_percentage
FROM $table_employees
WHERE is_active = 1
ORDER BY load_percentage DESC
", ARRAY_A);
echo '<h3>即将到期的任务</h3>';
if ($urgent_tasks) {
echo '<ul>';
foreach ($urgent_tasks as $task) {
$days_left = ceil((strtotime($task['deadline']) - time()) / (60 * 60 * 24));
$status_class = $this->get_status_class($task['status']);
$status_text = $this->get_status_text($task['status']);
echo '<li>';
echo '<strong>' . esc_html($task['task_name']) . '</strong><br>';
echo '截止: ' . esc_html($task['deadline']) . ' (' . $days_left . '天)';
echo ' | 状态: <span class="' . $status_class . '">' . $status_text . '</span>';
echo '</li>';
}
echo '</ul>';
} else {
echo '<p>没有即将到期的任务。</p>';
}
echo '<h3>员工工作负荷</h3>';
echo '<table style="width: 100%;">';
foreach ($employee_load as $employee) {
$percentage = $employee['load_percentage'];
$bar_color = $percentage < 60 ? 'green' : ($percentage < 85 ? 'orange' : 'red');
echo '<tr>';
echo '<td>' . esc_html($employee['name']) . '</td>';
echo '<td style="width: 60%; padding: 0 10px;">';
// 添加仪表板小工具
add_action('wp_dashboard_setup', array($this, 'add_dashboard_widgets'));
public function add_dashboard_widgets() {
wp_add_dashboard_widget(
'spa_task_overview',
'生产任务概览',
array($this, 'render_dashboard_widget')
);
}
public function render_dashboard_widget() {
global $wpdb;
$table_tasks = $wpdb->prefix . 'spa_tasks';
$table_employees = $wpdb->prefix . 'spa_employees';
// 获取紧急任务
$urgent_tasks = $wpdb->get_results("
SELECT * FROM $table_tasks
WHERE status IN (0, 1, 2)
AND deadline <= DATE_ADD(CURDATE(), INTERVAL 3 DAY)
ORDER BY deadline ASC
LIMIT 5
", ARRAY_A);
// 获取员工负荷情况
$employee_load = $wpdb->get_results("
SELECT name, current_workload, max_daily_tasks,
ROUND((current_workload / max_daily_tasks) * 100) as load_percentage
FROM $table_employees
WHERE is_active = 1
ORDER BY load_percentage DESC
", ARRAY_A);
echo '<h3>即将到期的任务</h3>';
if ($urgent_tasks) {
echo '<ul>';
foreach ($urgent_tasks as $task) {
$days_left = ceil((strtotime($task['deadline']) - time()) / (60 * 60 * 24));
$status_class = $this->get_status_class($task['status']);
$status_text = $this->get_status_text($task['status']);
echo '<li>';
echo '<strong>' . esc_html($task['task_name']) . '</strong><br>';
echo '截止: ' . esc_html($task['deadline']) . ' (' . $days_left . '天)';
echo ' | 状态: <span class="' . $status_class . '">' . $status_text . '</span>';
echo '</li>';
}
echo '</ul>';
} else {
echo '<p>没有即将到期的任务。</p>';
}
echo '<h3>员工工作负荷</h3>';
echo '<table style="width: 100%;">';
foreach ($employee_load as $employee) {
$percentage = $employee['load_percentage'];
$bar_color = $percentage < 60 ? 'green' : ($percentage < 85 ? 'orange' : 'red');
echo '<tr>';
echo '<td>' . esc_html($employee['name']) . '</td>';
echo '<td style="width: 60%; padding: 0 10px;">';


