首页 / 应用软件 / WordPress开发教程,集成网站用户反馈收集与需求投票系统

WordPress开发教程,集成网站用户反馈收集与需求投票系统

WordPress开发教程:集成用户反馈收集与需求投票系统

引言:为什么WordPress需要用户反馈系统

在当今互联网时代,用户参与度已成为网站成功的关键因素之一。无论是企业官网、博客还是电子商务平台,了解用户需求、收集反馈意见对于优化用户体验、提升产品价值至关重要。WordPress作为全球最流行的内容管理系统,虽然拥有丰富的插件生态系统,但有时特定需求仍需要通过代码二次开发来实现。

本教程将详细介绍如何在WordPress中通过代码开发集成用户反馈收集与需求投票系统。这种集成不仅能够增强用户参与感,还能为网站优化提供数据支持,帮助站长更好地理解用户需求,从而做出更明智的决策。

系统架构设计

1.1 功能需求分析

在开始编码之前,我们需要明确系统应具备的功能:

  1. 用户反馈收集:允许用户提交问题、建议或bug报告
  2. 需求投票系统:用户可以对提出的功能需求进行投票
  3. 反馈分类管理:将反馈按类型(如功能建议、bug报告、用户体验问题等)分类
  4. 状态跟踪:跟踪反馈的处理状态(如待处理、已审核、开发中、已解决等)
  5. 用户通知:当反馈状态更新时通知提交者
  6. 管理后台:管理员可以查看、管理和回复所有反馈
  7. 数据统计:提供反馈和投票数据的可视化统计

1.2 数据库设计

我们需要在WordPress数据库中添加以下自定义表:

-- 反馈主表
CREATE TABLE wp_feedback_items (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    type ENUM('feature', 'bug', 'improvement', 'other') DEFAULT 'feature',
    status ENUM('pending', 'reviewed', 'planned', 'in_progress', 'completed', 'rejected') DEFAULT 'pending',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL
);

-- 投票表
CREATE TABLE wp_feedback_votes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    feedback_id INT NOT NULL,
    user_id INT NOT NULL,
    vote_type ENUM('up', 'down') DEFAULT 'up',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY unique_vote (feedback_id, user_id),
    FOREIGN KEY (feedback_id) REFERENCES wp_feedback_items(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE CASCADE
);

-- 评论/回复表
CREATE TABLE wp_feedback_comments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    feedback_id INT NOT NULL,
    user_id INT,
    comment TEXT NOT NULL,
    is_admin BOOLEAN DEFAULT FALSE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (feedback_id) REFERENCES wp_feedback_items(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL
);

开发环境准备

2.1 创建自定义插件

首先,我们需要创建一个独立的WordPress插件来管理所有功能:

<?php
/**
 * Plugin Name: WordPress用户反馈与投票系统
 * Plugin URI: https://yourwebsite.com/
 * Description: 集成用户反馈收集与需求投票系统的WordPress插件
 * Version: 1.0.0
 * Author: 你的名字
 * License: GPL v2 or later
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('WPFB_VERSION', '1.0.0');
define('WPFB_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WPFB_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
require_once WPFB_PLUGIN_DIR . 'includes/class-feedback-system.php';

// 激活和停用钩子
register_activation_hook(__FILE__, array('Feedback_System', 'activate'));
register_deactivation_hook(__FILE__, array('Feedback_System', 'deactivate'));

// 初始化插件
add_action('plugins_loaded', array('Feedback_System', 'get_instance'));

2.2 创建数据库表

在插件激活时创建必要的数据库表:

class Feedback_System {
    private static $instance = null;
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->init_hooks();
    }
    
    private function init_hooks() {
        // 初始化数据库
        add_action('init', array($this, 'init'));
        
        // 添加管理菜单
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // 加载脚本和样式
        add_action('wp_enqueue_scripts', array($this, 'enqueue_public_scripts'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
        
        // 处理AJAX请求
        add_action('wp_ajax_submit_feedback', array($this, 'ajax_submit_feedback'));
        add_action('wp_ajax_nopriv_submit_feedback', array($this, 'ajax_submit_feedback'));
        add_action('wp_ajax_vote_feedback', array($this, 'ajax_vote_feedback'));
        add_action('wp_ajax_nopriv_vote_feedback', array($this, 'ajax_vote_feedback'));
    }
    
    public static function activate() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        
        // 创建反馈表
        $feedback_table = $wpdb->prefix . 'feedback_items';
        $sql = "CREATE TABLE IF NOT EXISTS $feedback_table (
            id INT AUTO_INCREMENT PRIMARY KEY,
            user_id INT,
            title VARCHAR(255) NOT NULL,
            content TEXT NOT NULL,
            type VARCHAR(50) DEFAULT 'feature',
            status VARCHAR(50) DEFAULT 'pending',
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
        ) $charset_collate;";
        
        // 创建投票表
        $votes_table = $wpdb->prefix . 'feedback_votes';
        $sql .= "CREATE TABLE IF NOT EXISTS $votes_table (
            id INT AUTO_INCREMENT PRIMARY KEY,
            feedback_id INT NOT NULL,
            user_id INT NOT NULL,
            vote_type VARCHAR(10) DEFAULT 'up',
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY unique_vote (feedback_id, user_id)
        ) $charset_collate;";
        
        // 创建评论表
        $comments_table = $wpdb->prefix . 'feedback_comments';
        $sql .= "CREATE TABLE IF NOT EXISTS $comments_table (
            id INT AUTO_INCREMENT PRIMARY KEY,
            feedback_id INT NOT NULL,
            user_id INT,
            comment TEXT NOT NULL,
            is_admin BOOLEAN DEFAULT FALSE,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
        
        // 添加版本号
        add_option('wpfb_version', WPFB_VERSION);
    }
}

前端反馈表单实现

3.1 创建反馈提交表单

我们需要创建一个用户友好的前端表单,让用户可以轻松提交反馈:

class Feedback_Form {
    
    public static function render_form() {
        // 检查用户是否登录
        $user_id = get_current_user_id();
        $user_name = $user_id ? wp_get_current_user()->display_name : '';
        $user_email = $user_id ? wp_get_current_user()->user_email : '';
        
        ob_start();
        ?>
        <div class="feedback-form-container">
            <h3>提交反馈或建议</h3>
            
            <?php if (isset($_GET['feedback_submitted']) && $_GET['feedback_submitted'] == 'success'): ?>
                <div class="feedback-success">
                    感谢您的反馈!我们已经收到您的提交。
                </div>
            <?php endif; ?>
            
            <form id="feedback-form" method="post" action="<?php echo admin_url('admin-ajax.php'); ?>">
                <input type="hidden" name="action" value="submit_feedback">
                <?php wp_nonce_field('submit_feedback_nonce', 'feedback_nonce'); ?>
                
                <div class="form-group">
                    <label for="feedback-title">标题 *</label>
                    <input type="text" id="feedback-title" name="title" required 
                           placeholder="请简要描述您的反馈或建议">
                </div>
                
                <div class="form-group">
                    <label for="feedback-type">反馈类型 *</label>
                    <select id="feedback-type" name="type" required>
                        <option value="">请选择类型</option>
                        <option value="feature">功能建议</option>
                        <option value="bug">错误报告</option>
                        <option value="improvement">改进建议</option>
                        <option value="other">其他</option>
                    </select>
                </div>
                
                <div class="form-group">
                    <label for="feedback-content">详细描述 *</label>
                    <textarea id="feedback-content" name="content" rows="6" required 
                              placeholder="请详细描述您的反馈或建议..."></textarea>
                </div>
                
                <?php if (!$user_id): ?>
                <div class="form-row">
                    <div class="form-group">
                        <label for="feedback-name">您的姓名 *</label>
                        <input type="text" id="feedback-name" name="user_name" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="feedback-email">电子邮箱 *</label>
                        <input type="email" id="feedback-email" name="user_email" required>
                    </div>
                </div>
                <?php endif; ?>
                
                <div class="form-group">
                    <button type="submit" class="submit-feedback-btn">提交反馈</button>
                    <div class="form-loading" style="display:none;">
                        提交中,请稍候...
                    </div>
                </div>
            </form>
        </div>
        
        <script>
        jQuery(document).ready(function($) {
            $('#feedback-form').on('submit', function(e) {
                e.preventDefault();
                
                var form = $(this);
                var submitBtn = form.find('.submit-feedback-btn');
                var loading = form.find('.form-loading');
                
                // 验证表单
                if (!form[0].checkValidity()) {
                    form[0].reportValidity();
                    return;
                }
                
                // 显示加载状态
                submitBtn.prop('disabled', true);
                loading.show();
                
                // 收集表单数据
                var formData = new FormData(this);
                
                // 发送AJAX请求
                $.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function(response) {
                        if (response.success) {
                            // 提交成功,重定向到成功页面
                            window.location.href = window.location.href + '?feedback_submitted=success';
                        } else {
                            alert(response.data || '提交失败,请重试。');
                            submitBtn.prop('disabled', false);
                            loading.hide();
                        }
                    },
                    error: function() {
                        alert('网络错误,请重试。');
                        submitBtn.prop('disabled', false);
                        loading.hide();
                    }
                });
            });
        });
        </script>
        <?php
        return ob_get_clean();
    }
}

3.2 创建短代码

为了让用户可以在任何文章或页面中插入反馈表单,我们创建一个短代码:

// 在Feedback_System类中添加短代码注册
add_shortcode('feedback_form', array($this, 'feedback_form_shortcode'));

public function feedback_form_shortcode($atts) {
    $atts = shortcode_atts(array(
        'title' => '提交反馈',
        'show_type' => true
    ), $atts, 'feedback_form');
    
    return Feedback_Form::render_form();
}

现在用户可以在文章或页面中使用 [feedback_form] 短代码来显示反馈表单。

需求投票系统实现

4.1 创建投票界面

投票系统允许用户对已有的反馈进行投票,帮助确定需求的优先级:

class Voting_System {
    
    public static function render_voting_section($feedback_id = null) {
        global $wpdb;
        
        if (!$feedback_id) {
            return '';
        }
        
        $user_id = get_current_user_id();
        $table_name = $wpdb->prefix . 'feedback_items';
        $votes_table = $wpdb->prefix . 'feedback_votes';
        
        // 获取反馈详情
        $feedback = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_name WHERE id = %d", $feedback_id
        ));
        
        if (!$feedback) {
            return '';
        }
        
        // 获取投票统计
        $upvotes = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $votes_table WHERE feedback_id = %d AND vote_type = 'up'", 
            $feedback_id
        ));
        
        $downvotes = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $votes_table WHERE feedback_id = %d AND vote_type = 'down'", 
            $feedback_id
        ));
        
        // 检查当前用户是否已投票
        $user_vote = null;
        if ($user_id) {
            $user_vote = $wpdb->get_var($wpdb->prepare(
                "SELECT vote_type FROM $votes_table WHERE feedback_id = %d AND user_id = %d", 
                $feedback_id, $user_id
            ));
        }
        
        ob_start();
        ?>
        <div class="feedback-voting" data-feedback-id="<?php echo esc_attr($feedback_id); ?>">
            <div class="vote-count">
                <span class="vote-total"><?php echo ($upvotes - $downvotes); ?></span>
                <span class="vote-label">票</span>
            </div>
            
            <div class="vote-buttons">
                <button class="vote-btn vote-up <?php echo ($user_vote == 'up') ? 'voted' : ''; ?>" 
                        data-vote-type="up" 
                        <?php echo (!$user_id) ? 'disabled title="请登录后投票"' : ''; ?>>
                    <span class="dashicons dashicons-thumbs-up"></span>
                    <span class="vote-count"><?php echo $upvotes; ?></span>
                </button>
                
                <button class="vote-btn vote-down <?php echo ($user_vote == 'down') ? 'voted' : ''; ?>" 
                        data-vote-type="down"
                        <?php echo (!$user_id) ? 'disabled title="请登录后投票"' : ''; ?>>
                    <span class="dashicons dashicons-thumbs-down"></span>
                    <span class="vote-count"><?php echo $downvotes; ?></span>
                </button>
            </div>
            
            <?php if (!$user_id): ?>
            <p class="vote-login-notice">请<a href="<?php echo wp_login_url(get_permalink()); ?>">登录</a>后投票</p>
            <?php endif; ?>
        </div>
        
        <script>
        jQuery(document).ready(function($) {
            $('.vote-btn').on('click', function(e) {
                e.preventDefault();
                
                var button = $(this);
                var feedbackId = button.closest('.feedback-voting').data('feedback-id');
                var voteType = button.data('vote-type');
                
                // 如果已经投票,则取消投票
                if (button.hasClass('voted')) {
                    var newVoteType = null;
                } else {
                    var newVoteType = voteType;
                }
                
                $.ajax({
                    url: '<?php echo admin_url("admin-ajax.php"); ?>',
                    type: 'POST',
                    data: {
                        action: 'vote_feedback',
                        feedback_id: feedbackId,
                        vote_type: newVoteType,
                        nonce: '<?php echo wp_create_nonce("vote_feedback_nonce"); ?>'
                    },
                    success: function(response) {
                        if (response.success) {
                            // 更新UI
                            var votingSection = button.closest('.feedback-voting');
                            votingSection.find('.vote-total').text(response.data.total_votes);
                            votingSection.find('.vote-up .vote-count').text(response.data.upvotes);
                            votingSection.find('.vote-down .vote-count').text(response.data.downvotes);
                            
                            // 更新按钮状态
                            votingSection.find('.vote-btn').removeClass('voted');
                            if (newVoteType) {
                                votingSection.find('.vote-btn[data-vote-type="' + newVoteType + '"]').addClass('voted');
                            }
                        } else {
                            alert(response.data || '投票失败,请重试。');
                        }
                    }
                });
            });
        });
        </script>
        <?php
        return ob_get_clean();
    }
}

4.2 处理投票的AJAX请求

// 在Feedback_System类中添加投票处理
public function ajax_vote_feedback() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'vote_feedback_nonce')) {
        wp_die('安全验证失败');
    }
    
    $user_id = get_current_user_id();
    if (!$user_id) {
        wp_send_json_error('请登录后投票');
    }
    
    $feedback_id = intval($_POST['feedback_id']);
    $vote_type = $_POST['vote_type'] ? sanitize_text_field($_POST['vote_type']) : null;
    
    global $wpdb;
    $votes_table = $wpdb->prefix . 'feedback_votes';
    
    // 检查是否已投票
    $existing_vote = $wpdb->get_row($wpdb->prepare(

WordPress开发教程:集成用户反馈收集与需求投票系统(续)

投票系统实现(续)

4.3 处理投票的AJAX请求(续)

// 在Feedback_System类中添加投票处理
public function ajax_vote_feedback() {
    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'vote_feedback_nonce')) {
        wp_die('安全验证失败');
    }
    
    $user_id = get_current_user_id();
    if (!$user_id) {
        wp_send_json_error('请登录后投票');
    }
    
    $feedback_id = intval($_POST['feedback_id']);
    $vote_type = $_POST['vote_type'] ? sanitize_text_field($_POST['vote_type']) : null;
    
    global $wpdb;
    $votes_table = $wpdb->prefix . 'feedback_votes';
    
    // 检查是否已投票
    $existing_vote = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM $votes_table WHERE feedback_id = %d AND user_id = %d", 
        $feedback_id, $user_id
    ));
    
    if ($existing_vote) {
        if ($vote_type) {
            // 更新现有投票
            $wpdb->update(
                $votes_table,
                array('vote_type' => $vote_type, 'created_at' => current_time('mysql')),
                array('id' => $existing_vote->id)
            );
        } else {
            // 删除投票(取消投票)
            $wpdb->delete(
                $votes_table,
                array('id' => $existing_vote->id)
            );
        }
    } else {
        if ($vote_type) {
            // 插入新投票
            $wpdb->insert(
                $votes_table,
                array(
                    'feedback_id' => $feedback_id,
                    'user_id' => $user_id,
                    'vote_type' => $vote_type,
                    'created_at' => current_time('mysql')
                )
            );
        }
    }
    
    // 重新计算投票统计
    $upvotes = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM $votes_table WHERE feedback_id = %d AND vote_type = 'up'", 
        $feedback_id
    ));
    
    $downvotes = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM $votes_table WHERE feedback_id = %d AND vote_type = 'down'", 
        $feedback_id
    ));
    
    $total_votes = $upvotes - $downvotes;
    
    wp_send_json_success(array(
        'total_votes' => $total_votes,
        'upvotes' => $upvotes,
        'downvotes' => $downvotes
    ));
}

反馈列表与展示页面

5.1 创建反馈列表页面

用户需要能够查看所有提交的反馈并进行投票:

class Feedback_List {
    
    public static function render_feedback_list($atts = array()) {
        global $wpdb;
        
        $atts = shortcode_atts(array(
            'type' => 'all',
            'status' => 'all',
            'per_page' => 10,
            'show_voting' => true,
            'show_filters' => true
        ), $atts, 'feedback_list');
        
        $page = isset($_GET['fb_page']) ? max(1, intval($_GET['fb_page'])) : 1;
        $offset = ($page - 1) * $atts['per_page'];
        
        $table_name = $wpdb->prefix . 'feedback_items';
        $votes_table = $wpdb->prefix . 'feedback_votes';
        
        // 构建查询条件
        $where_conditions = array('1=1');
        $query_params = array();
        
        if ($atts['type'] != 'all') {
            $where_conditions[] = "type = %s";
            $query_params[] = $atts['type'];
        }
        
        if ($atts['status'] != 'all') {
            $where_conditions[] = "status = %s";
            $query_params[] = $atts['status'];
        }
        
        $where_clause = implode(' AND ', $where_conditions);
        
        // 获取总数量
        $count_query = "SELECT COUNT(*) FROM $table_name WHERE $where_clause";
        if ($query_params) {
            $count_query = $wpdb->prepare($count_query, $query_params);
        }
        $total_items = $wpdb->get_var($count_query);
        $total_pages = ceil($total_items / $atts['per_page']);
        
        // 获取反馈列表
        $query = "SELECT f.*, 
                         COUNT(CASE WHEN v.vote_type = 'up' THEN 1 END) as upvotes,
                         COUNT(CASE WHEN v.vote_type = 'down' THEN 1 END) as downvotes
                  FROM $table_name f
                  LEFT JOIN $votes_table v ON f.id = v.feedback_id
                  WHERE $where_clause
                  GROUP BY f.id
                  ORDER BY (upvotes - downvotes) DESC, f.created_at DESC
                  LIMIT %d OFFSET %d";
        
        $query_params[] = $atts['per_page'];
        $query_params[] = $offset;
        
        $feedback_items = $wpdb->get_results($wpdb->prepare($query, $query_params));
        
        ob_start();
        ?>
        
        <div class="feedback-list-container">
            <?php if ($atts['show_filters']): ?>
            <div class="feedback-filters">
                <form method="get" class="filter-form">
                    <input type="hidden" name="fb_page" value="1">
                    
                    <div class="filter-group">
                        <label for="filter-type">反馈类型:</label>
                        <select id="filter-type" name="fb_type" onchange="this.form.submit()">
                            <option value="all" <?php selected($atts['type'], 'all'); ?>>全部类型</option>
                            <option value="feature" <?php selected($atts['type'], 'feature'); ?>>功能建议</option>
                            <option value="bug" <?php selected($atts['type'], 'bug'); ?>>错误报告</option>
                            <option value="improvement" <?php selected($atts['type'], 'improvement'); ?>>改进建议</option>
                        </select>
                    </div>
                    
                    <div class="filter-group">
                        <label for="filter-status">状态:</label>
                        <select id="filter-status" name="fb_status" onchange="this.form.submit()">
                            <option value="all" <?php selected($atts['status'], 'all'); ?>>全部状态</option>
                            <option value="pending" <?php selected($atts['status'], 'pending'); ?>>待处理</option>
                            <option value="reviewed" <?php selected($atts['status'], 'reviewed'); ?>>已审核</option>
                            <option value="planned" <?php selected($atts['status'], 'planned'); ?>>计划中</option>
                            <option value="in_progress" <?php selected($atts['status'], 'in_progress'); ?>>开发中</option>
                            <option value="completed" <?php selected($atts['status'], 'completed'); ?>>已完成</option>
                        </select>
                    </div>
                    
                    <button type="submit" class="filter-btn">筛选</button>
                </form>
            </div>
            <?php endif; ?>
            
            <div class="feedback-items">
                <?php if (empty($feedback_items)): ?>
                    <div class="no-feedback">
                        <p>暂无反馈记录</p>
                    </div>
                <?php else: ?>
                    <?php foreach ($feedback_items as $item): ?>
                        <?php echo self::render_feedback_item($item, $atts['show_voting']); ?>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
            
            <?php if ($total_pages > 1): ?>
            <div class="feedback-pagination">
                <?php
                echo paginate_links(array(
                    'base' => add_query_arg('fb_page', '%#%'),
                    'format' => '',
                    'prev_text' => '&laquo;',
                    'next_text' => '&raquo;',
                    'total' => $total_pages,
                    'current' => $page,
                    'add_args' => array(
                        'fb_type' => $atts['type'],
                        'fb_status' => $atts['status']
                    )
                ));
                ?>
            </div>
            <?php endif; ?>
        </div>
        
        <?php
        return ob_get_clean();
    }
    
    private static function render_feedback_item($item, $show_voting = true) {
        $type_labels = array(
            'feature' => '功能建议',
            'bug' => '错误报告',
            'improvement' => '改进建议',
            'other' => '其他'
        );
        
        $status_labels = array(
            'pending' => array('label' => '待处理', 'class' => 'status-pending'),
            'reviewed' => array('label' => '已审核', 'class' => 'status-reviewed'),
            'planned' => array('label' => '计划中', 'class' => 'status-planned'),
            'in_progress' => array('label' => '开发中', 'class' => 'status-in-progress'),
            'completed' => array('label' => '已完成', 'class' => 'status-completed'),
            'rejected' => array('label' => '已拒绝', 'class' => 'status-rejected')
        );
        
        $user_info = $item->user_id ? get_userdata($item->user_id) : null;
        $user_name = $user_info ? $user_info->display_name : '匿名用户';
        $user_avatar = $user_info ? get_avatar($item->user_id, 40) : get_avatar(0, 40);
        
        $total_votes = $item->upvotes - $item->downvotes;
        
        ob_start();
        ?>
        <div class="feedback-item" id="feedback-<?php echo $item->id; ?>">
            <div class="feedback-header">
                <div class="user-info">
                    <div class="user-avatar">
                        <?php echo $user_avatar; ?>
                    </div>
                    <div class="user-details">
                        <span class="user-name"><?php echo esc_html($user_name); ?></span>
                        <span class="feedback-date"><?php echo date('Y-m-d H:i', strtotime($item->created_at)); ?></span>
                    </div>
                </div>
                
                <div class="feedback-meta">
                    <span class="feedback-type type-<?php echo $item->type; ?>">
                        <?php echo $type_labels[$item->type]; ?>
                    </span>
                    <span class="feedback-status <?php echo $status_labels[$item->status]['class']; ?>">
                        <?php echo $status_labels[$item->status]['label']; ?>
                    </span>
                </div>
            </div>
            
            <div class="feedback-content">
                <h3 class="feedback-title"><?php echo esc_html($item->title); ?></h3>
                <div class="feedback-description">
                    <?php echo wpautop(esc_html($item->content)); ?>
                </div>
            </div>
            
            <div class="feedback-footer">
                <?php if ($show_voting): ?>
                <div class="feedback-voting-section">
                    <?php echo Voting_System::render_voting_section($item->id); ?>
                </div>
                <?php endif; ?>
                
                <div class="feedback-actions">
                    <a href="<?php echo add_query_arg('feedback_id', $item->id, get_permalink()); ?>" 
                       class="view-details-btn">
                        查看详情
                    </a>
                    <?php if (current_user_can('manage_options') || get_current_user_id() == $item->user_id): ?>
                    <button class="add-comment-btn" data-feedback-id="<?php echo $item->id; ?>">
                        添加评论
                    </button>
                    <?php endif; ?>
                </div>
            </div>
            
            <?php echo self::render_comments_section($item->id); ?>
        </div>
        <?php
        return ob_get_clean();
    }
}

5.2 添加短代码支持

// 在Feedback_System类中添加短代码
add_shortcode('feedback_list', array($this, 'feedback_list_shortcode'));

public function feedback_list_shortcode($atts) {
    return Feedback_List::render_feedback_list($atts);
}

管理后台界面开发

6.1 创建管理菜单和页面

class Feedback_Admin {
    
    public static function add_admin_menu() {
        // 主菜单
        add_menu_page(
            '用户反馈管理',
            '用户反馈',
            'manage_options',
            'feedback-management',
            array(__CLASS__, 'render_admin_page'),
            'dashicons-feedback',
            30
        );
        
        // 子菜单
        add_submenu_page(
            'feedback-management',
            '所有反馈',
            '所有反馈',
            'manage_options',
            'feedback-management',
            array(__CLASS__, 'render_admin_page')
        );
        
        add_submenu_page(
            'feedback-management',
            '反馈统计',
            '统计报表',
            'manage_options',
            'feedback-statistics',
            array(__CLASS__, 'render_statistics_page')
        );
        
        add_submenu_page(
            'feedback-management',
            '反馈设置',
            '设置',
            'manage_options',
            'feedback-settings',
            array(__CLASS__, 'render_settings_page')
        );
    }
    
    public static function render_admin_page() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'feedback_items';
        $votes_table = $wpdb->prefix . 'feedback_votes';
        
        // 处理批量操作
        if (isset($_POST['bulk_action']) && isset($_POST['feedback_ids'])) {
            self::handle_bulk_actions($_POST['bulk_action'], $_POST['feedback_ids']);
        }
        
        // 处理单个操作
        if (isset($_GET['action']) && isset($_GET['feedback_id'])) {
            self::handle_single_action($_GET['action'], $_GET['feedback_id']);
        }
        
        // 分页参数
        $per_page = 20;
        $page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
        $offset = ($page - 1) * $per_page;
        
        // 搜索和筛选条件
        $where_conditions = array('1=1');
        $query_params = array();
        
        if (!empty($_GET['s'])) {
            $where_conditions[] = "(title LIKE %s OR content LIKE %s)";
            $search_term = '%' . $wpdb->esc_like($_GET['s']) . '%';
            $query_params[] = $search_term;
            $query_params[] = $search_term;
        }
        
        if (!empty($_GET['type'])) {
            $where_conditions[] = "type = %s";
            $query_params[] = $_GET['type'];
        }
        
        if (!empty($_GET['status'])) {
            $where_conditions[] = "status = %s";
            $query_params[] = $_GET['status'];
        }
        
        $where_clause = implode(' AND ', $where_conditions);
        
        // 获取总数
        $count_query = "SELECT COUNT(*) FROM $table_name WHERE $where_clause";
        if ($query_params) {
            $count_query = $wpdb->prepare($count_query, $query_params);
        }
        $total_items = $wpdb->get_var($count_query);
        $total_pages = ceil($total_items / $per_page);
        
        // 获取数据
        $query = "SELECT f.*, 
                         u.user_login, u.display_name, u.user_email,
                         COUNT(CASE WHEN v.vote_type = 'up' THEN 1 END) as upvotes,
                         COUNT(CASE WHEN v.vote_type = 'down' THEN 1 END) as downvotes
                  FROM $table_name f
                  LEFT JOIN {$wpdb->users} u ON f.user_id = u.ID
                  LEFT JOIN $votes_table v ON f.id = v.feedback_id
                  WHERE $where_clause
                  GROUP BY f.id
                  ORDER BY f.created_at DESC
                  LIMIT %d OFFSET %d";
        
        $query_params[] = $per_page;
        $query_params[] = $offset;
        
        $feedback_items = $wpdb->get_results($wpdb->prepare($query, $query_params));
        
        ?>
        <div class="wrap">
            <h1 class="wp-heading-inline">用户反馈管理</h1>
            
            <form method="get" class="search-form">
                <input type="hidden" name="page" value="feedback-management">
                
                <div class="tablenav top">
                    <div class="alignleft actions bulkactions">
                        <select name="bulk_action">
                            <option value="">批量操作</option>
                            <option value="mark_reviewed">标记为已审核</option>
                            <option value="mark_in_progress">标记为开发中</option>
                            <option value="mark_completed">标记为已完成</option>
                            <option value="delete">删除</option>
                        </select>
                        <button type="submit" class="button action">应用</button>
                    </div>
                    
                    <div class="alignleft actions">
                        <select name="type">
                            <option value="">所有类型</option>
                            <option value="feature" <?php selected(@$_GET['type'], 'feature'); ?>>功能建议</option>
                            <option value="bug" <?php selected(@$_GET['type'], 'bug'); ?>>错误报告</option>
                            <option value="improvement" <?php selected(@$_GET['type'], 'improvement'); ?>>改进建议</option>
                        </select>
                        
                        <select name="status">
                            <option value="">所有状态</option>
                            <option value="pending" <?php selected(@$_GET['status'], 'pending'); ?>>待处理</option>
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5190.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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