WordPress开发教程:打造内部团队协作与任务看板,通过WordPress程序的代码二次开发实现常用互联网小工具功能
引言:为什么选择WordPress作为团队协作平台?
在当今数字化工作环境中,高效的团队协作工具已成为企业提升生产力的关键因素。虽然市面上已有Trello、Asana、Jira等专业协作工具,但许多企业仍面临数据孤岛、定制化不足和高昂成本等问题。此时,利用WordPress构建内部协作平台成为一个值得考虑的解决方案。
WordPress作为全球最流行的内容管理系统,占据互联网超过43%的网站份额。其优势不仅在于易用性和庞大的插件生态,更在于其开源特性带来的无限定制可能。通过代码二次开发,我们可以将WordPress从一个简单的博客系统转变为功能强大的内部协作平台,同时集成各种常用互联网小工具,打造一体化工作环境。
本教程将详细指导您如何通过WordPress二次开发,构建一个包含任务看板、团队协作和常用工具的综合性平台,既能满足特定业务需求,又能保持成本可控。
第一部分:环境准备与基础配置
1.1 WordPress开发环境搭建
在开始开发前,我们需要搭建一个适合的开发环境。推荐使用本地开发环境,如Local by Flywheel、XAMPP或MAMP,这些工具可以快速配置PHP、MySQL和Web服务器环境。
对于团队协作平台的开发,建议选择以下技术栈:
- WordPress 5.8或更高版本
- PHP 7.4或更高版本(推荐PHP 8.0+)
- MySQL 5.6或更高版本
- 代码编辑器(VS Code、PHPStorm等)
安装WordPress后,需要进行一些基础配置优化:
- 设置固定链接结构为“文章名”模式,便于API调用
- 禁用不必要的插件和主题,保持系统简洁
- 配置WP_DEBUG模式,便于开发调试
1.2 创建自定义主题或插件
对于团队协作平台,我们有两种开发方式:创建自定义主题或开发独立插件。考虑到协作功能的独立性,建议创建专用插件,这样可以在任何主题上使用。
创建插件的基本结构:
team-collaboration-platform/
├── team-collaboration-platform.php
├── includes/
│ ├── class-database.php
│ ├── class-task-manager.php
│ └── class-user-manager.php
├── assets/
│ ├── css/
│ ├── js/
│ └── images/
├── templates/
├── languages/
└── vendor/
插件主文件头部信息:
<?php
/**
* Plugin Name: 团队协作与任务看板平台
* Plugin URI: https://yourcompany.com/
* Description: 基于WordPress的团队协作、任务管理和工具集成平台
* Version: 1.0.0
* Author: 您的团队
* License: GPL v2 or later
*/
第二部分:数据库设计与用户权限系统
2.1 自定义数据库表设计
团队协作平台需要存储任务、项目、团队成员关系等复杂数据。虽然可以使用WordPress自带的文章类型,但对于复杂关系,创建自定义表更为合适。
创建数据库表的示例代码:
class Collaboration_Database {
public function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 项目表
$projects_table = $wpdb->prefix . 'collab_projects';
$projects_sql = "CREATE TABLE IF NOT EXISTS $projects_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(200) NOT NULL,
description text,
status varchar(50) DEFAULT 'active',
created_by bigint(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 任务表
$tasks_table = $wpdb->prefix . 'collab_tasks';
$tasks_sql = "CREATE TABLE IF NOT EXISTS $tasks_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
project_id mediumint(9) NOT NULL,
title varchar(500) NOT NULL,
description longtext,
status varchar(50) DEFAULT 'todo',
priority varchar(20) DEFAULT 'medium',
assignee_id bigint(20),
due_date date,
estimated_hours decimal(5,2),
actual_hours decimal(5,2) DEFAULT 0,
created_by bigint(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY project_id (project_id),
KEY assignee_id (assignee_id)
) $charset_collate;";
// 团队成员关系表
$team_members_table = $wpdb->prefix . 'collab_team_members';
$team_members_sql = "CREATE TABLE IF NOT EXISTS $team_members_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
project_id mediumint(9) NOT NULL,
user_id bigint(20) NOT NULL,
role varchar(50) DEFAULT 'member',
joined_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY project_user (project_id, user_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($projects_sql);
dbDelta($tasks_sql);
dbDelta($team_members_sql);
}
}
2.2 用户角色与权限系统
WordPress自带的用户角色系统可能无法满足团队协作的复杂需求,我们需要扩展或创建自定义角色系统。
创建自定义用户角色和权限:
class User_Role_Manager {
public function add_collaboration_roles() {
// 添加项目经理角色
add_role('project_manager', '项目经理', array(
'read' => true,
'edit_posts' => true,
'delete_posts' => true,
'publish_posts' => true,
'upload_files' => true,
'manage_collab_projects' => true,
'assign_collab_tasks' => true,
'edit_collab_tasks' => true,
'delete_collab_tasks' => false,
));
// 添加团队成员角色
add_role('team_member', '团队成员', array(
'read' => true,
'edit_posts' => true,
'upload_files' => true,
'edit_assigned_tasks' => true,
'update_task_status' => true,
));
}
public function add_capabilities_to_roles() {
// 为管理员添加所有协作权限
$admin_role = get_role('administrator');
$admin_role->add_cap('manage_collab_projects');
$admin_role->add_cap('assign_collab_tasks');
$admin_role->add_cap('edit_collab_tasks');
$admin_role->add_cap('delete_collab_tasks');
$admin_role->add_cap('view_all_tasks');
}
}
第三部分:任务看板系统开发
3.1 看板式任务管理界面
看板(Kanban)是团队协作中常用的任务可视化工具。我们将使用HTML5、CSS3和JavaScript(配合Vue.js或React)创建交互式看板界面。
创建看板主模板:
class Task_Kanban {
public function display_kanban_board($project_id = null) {
ob_start();
?>
<div id="task-kanban-app" data-project-id="<?php echo esc_attr($project_id); ?>">
<div class="kanban-header">
<h2>任务看板</h2>
<div class="kanban-actions">
<button class="add-task-btn" @click="showAddTaskModal">+ 添加任务</button>
<button class="filter-btn" @click="toggleFilters">筛选</button>
</div>
</div>
<div class="kanban-filters" v-if="showFilters">
<!-- 筛选条件组件 -->
</div>
<div class="kanban-board">
<div class="kanban-column" v-for="column in columns" :key="column.id">
<div class="column-header">
<h3>{{ column.name }} ({{ column.tasks.length }})</h3>
</div>
<div class="column-body"
@dragover.prevent
@drop="dropTask($event, column.id)">
<div class="task-card"
v-for="task in column.tasks"
:key="task.id"
draggable="true"
@dragstart="dragTask($event, task.id)">
<div class="task-priority" :class="'priority-' + task.priority"></div>
<div class="task-content">
<h4>{{ task.title }}</h4>
<p class="task-description">{{ task.description | truncate(100) }}</p>
<div class="task-meta">
<span class="assignee">{{ task.assignee_name }}</span>
<span class="due-date" :class="{ 'overdue': task.isOverdue }">
{{ task.due_date | formatDate }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 任务详情模态框 -->
<div class="modal" v-if="showTaskModal">
<!-- 模态框内容 -->
</div>
</div>
<?php
return ob_get_clean();
}
}
3.2 拖放功能与实时更新
实现拖放功能和实时更新是看板系统的核心。我们将使用HTML5 Drag & Drop API和WebSocket或AJAX轮询实现实时同步。
JavaScript拖放实现:
// 在Vue组件中实现拖放逻辑
const TaskKanban = {
data() {
return {
columns: [
{ id: 'todo', name: '待处理', tasks: [] },
{ id: 'in_progress', name: '进行中', tasks: [] },
{ id: 'review', name: '审核中', tasks: [] },
{ id: 'done', name: '已完成', tasks: [] }
],
draggedTaskId: null,
showFilters: false,
showTaskModal: false
};
},
methods: {
dragTask(event, taskId) {
event.dataTransfer.setData('text/plain', taskId);
this.draggedTaskId = taskId;
},
async dropTask(event, columnId) {
event.preventDefault();
const taskId = event.dataTransfer.getData('text/plain');
// 发送AJAX请求更新任务状态
try {
const response = await fetch('/wp-json/collab/v1/tasks/' + taskId, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': collabData.nonce
},
body: JSON.stringify({
status: columnId
})
});
if (response.ok) {
this.moveTaskToColumn(taskId, columnId);
this.showNotification('任务状态已更新', 'success');
}
} catch (error) {
console.error('更新任务失败:', error);
this.showNotification('更新失败,请重试', 'error');
}
},
moveTaskToColumn(taskId, targetColumnId) {
// 在前端移动任务卡片
let task = null;
let sourceColumnIndex = -1;
// 查找任务所在列
this.columns.forEach((column, colIndex) => {
const taskIndex = column.tasks.findIndex(t => t.id == taskId);
if (taskIndex !== -1) {
task = column.tasks[taskIndex];
sourceColumnIndex = colIndex;
column.tasks.splice(taskIndex, 1);
}
});
// 将任务添加到目标列
if (task && sourceColumnIndex !== -1) {
const targetColumn = this.columns.find(col => col.id === targetColumnId);
if (targetColumn) {
task.status = targetColumnId;
targetColumn.tasks.push(task);
}
}
},
// 实时更新任务状态
setupRealTimeUpdates() {
// 使用WebSocket或AJAX轮询
if ('WebSocket' in window) {
this.setupWebSocket();
} else {
this.setupPolling();
}
},
setupWebSocket() {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/ws/collab`;
this.ws = new WebSocket(wsUrl);
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'task_update') {
this.updateTask(data.task);
} else if (data.type === 'task_created') {
this.addTask(data.task);
}
};
}
},
mounted() {
this.loadTasks();
this.setupRealTimeUpdates();
}
};
第四部分:团队协作功能实现
4.1 实时聊天与讨论系统
团队协作离不开实时沟通。我们将集成一个简单的实时聊天系统,支持一对一和群组聊天。
聊天系统数据库设计:
// 聊天消息表
$chat_messages_sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}collab_chat_messages (
id bigint(20) NOT NULL AUTO_INCREMENT,
room_id varchar(100) NOT NULL,
sender_id bigint(20) NOT NULL,
message_type varchar(20) DEFAULT 'text',
content text NOT NULL,
attachment_id bigint(20),
parent_id bigint(20),
is_read tinyint(1) DEFAULT 0,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY room_id (room_id),
KEY sender_id (sender_id),
KEY created_at (created_at)
) $charset_collate;";
// 聊天室表
$chat_rooms_sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}collab_chat_rooms (
id varchar(100) NOT NULL,
name varchar(200),
type varchar(20) DEFAULT 'direct', -- direct, group, project
project_id mediumint(9),
created_by bigint(20),
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 聊天室成员表
$chat_room_members_sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}collab_chat_room_members (
id bigint(20) NOT NULL AUTO_INCREMENT,
room_id varchar(100) NOT NULL,
user_id bigint(20) NOT NULL,
joined_at datetime DEFAULT CURRENT_TIMESTAMP,
last_seen_at datetime,
PRIMARY KEY (id),
UNIQUE KEY room_user (room_id, user_id)
) $charset_collate;";
实时聊天前端实现:
class ChatSystem {
constructor() {
this.socket = null;
this.currentRoom = null;
this.initialize();
}
initialize() {
this.connectWebSocket();
this.bindEvents();
this.loadChatRooms();
}
connectWebSocket() {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/ws/chat`;
this.socket = new WebSocket(wsUrl);
this.socket.onopen = () => {
console.log('WebSocket连接已建立');
this.authenticate();
};
this.socket.onmessage = (event) => {
this.handleMessage(JSON.parse(event.data));
};
this.socket.onclose = () => {
console.log('WebSocket连接已关闭,尝试重连...');
setTimeout(() => this.connectWebSocket(), 3000);
};
}
authenticate() {
this.send({
type: 'auth',
token: this.getAuthToken()
});
}
sendMessage(content, roomId) {
const message = {
type: 'chat_message',
room_id: roomId,
content: content,
timestamp: new Date().toISOString()
};
this.send(message);
// 本地显示消息
this.displayMessage({
...message,
sender_id: currentUserId,
sender_name: currentUserName,
is_own: true
});
}
handleMessage(data) {
switch (data.type) {
case 'chat_message':
this.displayMessage(data.message);
break;
case 'user_online':
this.updateUserStatus(data.user_id, true);
break;
case 'user_offline':
this.updateUserStatus(data.user_id, false);
break;
case 'typing':
this.showTypingIndicator(data.user_id, data.room_id);
break;
}
}
displayMessage(message) {
const chatContainer = document.querySelector(`.chat-room[data-room-id="${message.room_id}"] .chat-messages`);
const messageElement = document.createElement('div');
messageElement.className = `chat-message ${message.is_own ? 'own-message' : 'other-message'}`;
messageElement.innerHTML = `
<div class="message-sender">${message.sender_name}</div>
<div class="message-content">${this.formatMessageContent(message)}</div>
<div class="message-time">${this.formatTime(message.timestamp)}</div>
`;
chatContainer.appendChild(messageElement);
chatContainer.scrollTop = chatContainer.scrollHeight;
// 播放消息提示音(如果不是自己的消息)
if (!message.is_own) {
this.playNotificationSound();
}
}
}
4.2 文件共享与版本控制
文件共享是团队协作的重要功能。我们将扩展WordPress媒体库,添加团队共享文件夹和版本控制功能。
文件共享系统实现:
class File_Sharing_System {
4.2 文件共享与版本控制(续)
class File_Sharing_System {
public function create_team_folders() {
// 为每个项目创建专用文件夹
add_action('project_created', function($project_id) {
$project = $this->get_project($project_id);
$folder_name = sanitize_title($project->name) . '-' . $project_id;
$upload_dir = wp_upload_dir();
$team_folder = $upload_dir['basedir'] . '/team-files/' . $folder_name;
if (!file_exists($team_folder)) {
wp_mkdir_p($team_folder);
// 创建子文件夹结构
$subfolders = ['documents', 'images', 'designs', 'code', 'archive'];
foreach ($subfolders as $subfolder) {
wp_mkdir_p($team_folder . '/' . $subfolder);
}
// 记录文件夹信息到数据库
$this->save_folder_to_db($project_id, $folder_name, $team_folder);
}
});
}
public function handle_file_upload($file, $project_id, $user_id) {
// 验证文件类型和大小
$allowed_types = $this->get_allowed_file_types();
$max_size = 100 * 1024 * 1024; // 100MB
if ($file['size'] > $max_size) {
return new WP_Error('file_too_large', '文件大小不能超过100MB');
}
$file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($file_ext, $allowed_types)) {
return new WP_Error('invalid_file_type', '不支持的文件类型');
}
// 生成唯一文件名
$unique_name = wp_unique_filename($this->get_project_upload_dir($project_id), $file['name']);
// 移动文件
$destination = $this->get_project_upload_dir($project_id) . '/' . $unique_name;
if (move_uploaded_file($file['tmp_name'], $destination)) {
// 保存文件信息到数据库
$file_id = $this->save_file_metadata(array(
'project_id' => $project_id,
'user_id' => $user_id,
'original_name' => $file['name'],
'file_name' => $unique_name,
'file_path' => $destination,
'file_size' => $file['size'],
'file_type' => $file_ext,
'version' => 1
));
// 生成缩略图(如果是图片)
if (in_array($file_ext, ['jpg', 'jpeg', 'png', 'gif'])) {
$this->generate_thumbnails($destination, $file_id);
}
return $file_id;
}
return new WP_Error('upload_failed', '文件上传失败');
}
public function create_file_version($file_id, $new_file, $user_id, $comment = '') {
global $wpdb;
// 获取原文件信息
$original = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}collab_files WHERE id = %d", $file_id
));
if (!$original) {
return new WP_Error('file_not_found', '文件不存在');
}
// 创建新版本
$new_version = $original->version + 1;
// 保存旧版本到版本历史
$wpdb->insert("{$wpdb->prefix}collab_file_versions", array(
'file_id' => $file_id,
'version' => $original->version,
'file_name' => $original->file_name,
'file_path' => $original->file_path,
'user_id' => $user_id,
'comment' => $comment,
'created_at' => current_time('mysql')
));
// 更新主文件记录
$wpdb->update("{$wpdb->prefix}collab_files", array(
'file_name' => $new_file['name'],
'file_path' => $new_file['path'],
'file_size' => $new_file['size'],
'version' => $new_version,
'updated_at' => current_time('mysql')
), array('id' => $file_id));
return $new_version;
}
public function get_file_version_history($file_id) {
global $wpdb;
return $wpdb->get_results($wpdb->prepare(
"SELECT v.*, u.display_name as user_name
FROM {$wpdb->prefix}collab_file_versions v
LEFT JOIN {$wpdb->users} u ON v.user_id = u.ID
WHERE v.file_id = %d
ORDER BY v.version DESC",
$file_id
));
}
}
第五部分:常用互联网小工具集成
5.1 代码片段共享与协作编辑器
class Code_Collaboration_Tool {
public function init() {
// 注册代码片段自定义文章类型
add_action('init', array($this, 'register_code_snippet_post_type'));
// 添加代码编辑器短代码
add_shortcode('code_editor', array($this, 'code_editor_shortcode'));
// 注册REST API端点
add_action('rest_api_init', array($this, 'register_code_api'));
}
public function register_code_snippet_post_type() {
$args = array(
'public' => true,
'label' => '代码片段',
'supports' => array('title', 'editor', 'author', 'revisions'),
'show_in_rest' => true,
'capability_type' => 'code_snippet',
'capabilities' => array(
'edit_posts' => 'edit_code_snippets',
'edit_others_posts' => 'edit_others_code_snippets',
'publish_posts' => 'publish_code_snippets',
'read_post' => 'read_code_snippet',
'delete_post' => 'delete_code_snippet'
)
);
register_post_type('code_snippet', $args);
}
public function code_editor_shortcode($atts) {
$atts = shortcode_atts(array(
'language' => 'javascript',
'theme' => 'monokai',
'height' => '400px',
'readonly' => false,
'snippet_id' => 0
), $atts);
ob_start();
?>
<div class="code-collaboration-editor"
data-language="<?php echo esc_attr($atts['language']); ?>"
data-theme="<?php echo esc_attr($atts['theme']); ?>"
data-snippet-id="<?php echo esc_attr($atts['snippet_id']); ?>">
<div class="editor-toolbar">
<select class="language-selector">
<option value="javascript">JavaScript</option>
<option value="php">PHP</option>
<option value="python">Python</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="sql">SQL</option>
</select>
<button class="run-code-btn">运行代码</button>
<button class="save-code-btn">保存</button>
<button class="share-code-btn">分享</button>
<div class="collaborators">
<span class="online-users">在线用户: <span class="count">0</span></span>
</div>
</div>
<div class="editor-container" style="height: <?php echo esc_attr($atts['height']); ?>;">
<div class="code-editor" id="code-editor-<?php echo uniqid(); ?>"></div>
</div>
<div class="output-container">
<div class="output-header">输出结果</div>
<div class="output-content"></div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
initializeCodeEditor('code-editor-<?php echo uniqid(); ?>', {
language: '<?php echo $atts["language"]; ?>',
theme: '<?php echo $atts["theme"]; ?>',
readonly: <?php echo $atts["readonly"] ? 'true' : 'false'; ?>,
snippetId: <?php echo $atts["snippet_id"]; ?>
});
});
</script>
<?php
return ob_get_clean();
}
public function register_code_api() {
register_rest_route('collab/v1', '/code/execute', array(
'methods' => 'POST',
'callback' => array($this, 'execute_code'),
'permission_callback' => function() {
return current_user_can('edit_code_snippets');
}
));
register_rest_route('collab/v1', '/code/save', array(
'methods' => 'POST',
'callback' => array($this, 'save_code_snippet'),
'permission_callback' => function() {
return current_user_can('edit_code_snippets');
}
));
}
public function execute_code($request) {
$code = $request->get_param('code');
$language = $request->get_param('language');
// 安全执行代码(使用沙箱环境)
$result = $this->safe_execute_code($code, $language);
return rest_ensure_response(array(
'success' => true,
'output' => $result['output'],
'error' => $result['error'],
'execution_time' => $result['execution_time']
));
}
}
5.2 API测试工具与Webhook管理
class API_Testing_Tool {
private $endpoints = array();
public function init() {
add_action('admin_menu', array($this, 'add_api_testing_page'));
add_action('wp_ajax_save_api_endpoint', array($this, 'save_api_endpoint'));
add_action('wp_ajax_test_api_endpoint', array($this, 'test_api_endpoint'));
add_action('wp_ajax_save_webhook', array($this, 'save_webhook'));
}
public function add_api_testing_page() {
add_menu_page(
'API测试工具',
'API测试',
'manage_options',
'api-testing-tool',
array($this, 'render_api_testing_page'),
'dashicons-rest-api',
30
);
}
public function render_api_testing_page() {
?>
<div class="wrap api-testing-tool">
<h1>API测试与Webhook管理</h1>
<div class="api-tool-container">
<!-- API测试界面 -->
<div class="api-tester-section">
<h2>API请求测试</h2>
<div class="request-builder">
<div class="request-method">
<select id="request-method">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="PATCH">PATCH</option>
</select>
<input type="text" id="request-url" placeholder="https://api.example.com/endpoint" style="width: 60%;">
<button id="send-request" class="button button-primary">发送请求</button>
</div>
<div class="request-tabs">
<ul>
<li><a href="#params-tab">参数</a></li>
<li><a href="#headers-tab">请求头</a></li>
<li><a href="#body-tab">请求体</a></li>
<li><a href="#auth-tab">认证</a></li>
</ul>
<div id="params-tab">
<table class="params-table">
<thead>
<tr>
<th>参数名</th>
<th>值</th>
<th>操作</th>
</tr>
</thead>
<tbody id="params-body">
<tr>
<td><input type="text" class="param-key" placeholder="参数名"></td>
<td><input type="text" class="param-value" placeholder="值"></td>
<td><button class="remove-param button">删除</button></td>
</tr>
</tbody>
</table>
<button id="add-param" class="button">添加参数</button>
</div>
<div id="headers-tab">
<!-- 请求头配置界面 -->
</div>
<div id="body-tab">
<select id="body-type">
<option value="none">无</option>
<option value="form-data">表单数据</option>
<option value="x-www-form-urlencoded">x-www-form-urlencoded</option>
<option value="raw">原始数据</option>
<option value="json">JSON</option>
</select>
<textarea id="request-body" rows="10" style="width: 100%;"></textarea>
</div>
<div id="auth-tab">
<!-- 认证配置界面 -->
</div>
</div>
</div>
<div class="response-section">
<h3>响应结果</h3>
<div class="response-info">
<div class="response-status">
状态码: <span id="response-status">-</span>
响应时间: <span id="response-time">-</span>ms
大小: <span id="response-size">-</span>
</div>
<div class="response-tabs">
<ul>
<li><a href="#response-body-tab">响应体</a></li>
<li><a href="#response-headers-tab">响应头</a></li>
<li><a href="#response-cookies-tab">Cookies</a></li>
</ul>
<div id="response-body-tab">
<pre id="response-body"></pre>
</div>
<div id="response-headers-tab">
<pre id="response-headers"></pre>
</div>
</div>
</div>
</div>
</div>
<!-- Webhook管理界面 -->
<div class="webhook-manager-section">
<h2>Webhook管理</h2>
<button id="add-webhook" class="button button-primary">添加Webhook</button>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>名称</th>
<th>URL</th>
<th>事件</th>
<th>状态</th>
<th>最后触发</th>
<th>操作</th>
</tr>
</thead>
<tbody id="webhooks-list">
<?php $this->render_webhooks_list(); ?>
</tbody>
</table>
<div class="webhook-details" style="display: none;">
<h3>Webhook详情</h3>
<form id="webhook-form">
<input type="hidden" id="webhook-id">
<table class="form-table">
<tr>
<th><label for="webhook-name">名称</label></th>
<td><input type="text" id="webhook-name" class="regular-text" required></td>
</tr>
<tr>
<th><label for="webhook-url">URL</label></th>
<td><input type="url" id="webhook-url" class="regular-text" required></td>
</tr>
<tr>
<th><label for="webhook-events">触发事件</label></th>
<td>
<select id="webhook-events" multiple style="width: 100%; height: 100px;">
<option value="task_created">任务创建</option>
<option value="task_updated">任务更新</option>
<option value="task_completed">任务完成</option>
<option value="file_uploaded">文件上传</option>
<option value="comment_added">评论添加</option>
<option value="user_joined">用户加入</option>
</select>
</td>
</tr>
<tr>
<th><label for="webhook-secret">签名密钥</label></th>
<td>
<input type="text" id="webhook-secret" class="regular-text">
<button type="button" id="generate-secret" class="button">生成密钥</button>
</td>
</tr>
<tr>
<th><label for="webhook-active">状态</label></th>
<td>
<label>
<input type="checkbox" id="webhook-active" checked> 启用
</label>
</td>
</tr>
</table>
<div class="submit">
<button type="submit" class="button button-primary">保存</button>
<button type="button" id="cancel-webhook" class="button">取消</button>
<button type="button" id="test-webhook" class="button">测试Webhook</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
// API测试功能
$('#send-request').on('click', function() {
const method = $('#request-method').val();
const url = $('#request-url').val();
const params = {};
$('#params-body tr').each(function() {
const key = $(this).find('.param-key').val();
