首页 / 应用软件 / WordPress开发教程,打造内部团队协作与任务看板

WordPress开发教程,打造内部团队协作与任务看板

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后,需要进行一些基础配置优化:

  1. 设置固定链接结构为“文章名”模式,便于API调用
  2. 禁用不必要的插件和主题,保持系统简洁
  3. 配置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();
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5086.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部