WordPress小批量定制插件实现生产任务智能派工教程
概述
在现代生产制造企业中,任务派工是生产管理的核心环节。本教程将指导您开发一个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>';
}
}
AJAX处理与API接口
// 在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;">';
