文章目录[隐藏]
详细指南:在WordPress中集成在线客服会话存档与质检分析系统
摘要
随着电子商务和在线服务的快速发展,在线客服系统已成为企业与客户沟通的重要桥梁。然而,仅仅拥有客服系统并不足够,如何有效管理、存档和分析客服会话数据,提升服务质量,已成为企业数字化转型的关键环节。本文将详细介绍如何在WordPress平台中通过代码二次开发,集成在线客服会话存档与质检分析系统,实现这一常用互联网小工具功能。我们将从系统架构设计、数据库规划、前后端开发到数据分析功能实现,提供完整的技术解决方案。
一、系统需求分析与架构设计
1.1 业务需求分析
在开始技术实现之前,我们首先需要明确系统的业务需求:
- 会话存档功能:自动保存所有在线客服会话记录,包括文字、图片、文件等多媒体内容
- 质检分析功能:对客服会话进行质量评估,包括响应时间、服务态度、问题解决率等指标
- 数据可视化:通过图表展示客服绩效、会话趋势、常见问题等数据
- 权限管理:不同角色的用户(管理员、客服主管、普通客服)拥有不同的数据访问权限
- 搜索与筛选:支持按时间、客服人员、客户、关键词等多维度检索会话记录
- 实时监控:实时查看当前在线会话状态和客服工作状态
1.2 技术架构设计
基于WordPress的扩展性,我们设计以下技术架构:
- 前端展示层:使用WordPress主题模板和自定义页面展示数据
- 业务逻辑层:通过自定义插件处理会话数据的存储、分析和展示逻辑
- 数据存储层:扩展WordPress数据库,创建专门的数据表存储会话和质检数据
- 第三方集成层:与主流在线客服系统(如LiveChat、Zendesk、自定义系统)API对接
- 数据分析层:集成数据分析工具和算法,实现智能质检功能
1.3 开发环境准备
在开始开发前,确保具备以下环境:
- WordPress 5.0+ 版本
- PHP 7.4+ 版本
- MySQL 5.6+ 或 MariaDB 10.1+
- 代码编辑器(VS Code、PHPStorm等)
- 本地开发环境(XAMPP、MAMP、Local等)
二、数据库设计与扩展
2.1 自定义数据表设计
为了存储客服会话和质检数据,我们需要在WordPress数据库中添加以下数据表:
-- 客服会话主表
CREATE TABLE wp_chat_sessions (
session_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
session_key VARCHAR(100) NOT NULL,
customer_id BIGINT(20) UNSIGNED,
customer_name VARCHAR(255),
customer_email VARCHAR(255),
agent_id BIGINT(20) UNSIGNED,
agent_name VARCHAR(255),
start_time DATETIME NOT NULL,
end_time DATETIME,
duration INT(11),
status ENUM('active', 'closed', 'transferred', 'timeout') DEFAULT 'active',
channel VARCHAR(50),
rating TINYINT(1),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (session_id),
UNIQUE KEY session_key (session_key),
KEY customer_id (customer_id),
KEY agent_id (agent_id),
KEY start_time (start_time)
);
-- 会话消息表
CREATE TABLE wp_chat_messages (
message_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
session_id BIGINT(20) UNSIGNED NOT NULL,
sender_type ENUM('customer', 'agent', 'system') NOT NULL,
sender_id BIGINT(20) UNSIGNED,
message_type ENUM('text', 'image', 'file', 'emoji', 'system') DEFAULT 'text',
content LONGTEXT,
media_url VARCHAR(500),
file_name VARCHAR(255),
file_size INT(11),
sent_time DATETIME NOT NULL,
read_status TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (message_id),
KEY session_id (session_id),
KEY sent_time (sent_time),
FOREIGN KEY (session_id) REFERENCES wp_chat_sessions(session_id) ON DELETE CASCADE
);
-- 质检分析表
CREATE TABLE wp_chat_quality (
quality_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
session_id BIGINT(20) UNSIGNED NOT NULL,
evaluator_id BIGINT(20) UNSIGNED,
evaluation_time DATETIME,
response_time_score TINYINT(1),
professionalism_score TINYINT(1),
problem_solving_score TINYINT(1),
communication_score TINYINT(1),
overall_score DECIMAL(3,2),
positive_keywords TEXT,
negative_keywords TEXT,
tags VARCHAR(500),
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (quality_id),
UNIQUE KEY session_evaluator (session_id, evaluator_id),
KEY session_id (session_id),
KEY evaluator_id (evaluator_id),
FOREIGN KEY (session_id) REFERENCES wp_chat_sessions(session_id) ON DELETE CASCADE
);
-- 客服绩效表
CREATE TABLE wp_agent_performance (
performance_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
agent_id BIGINT(20) UNSIGNED NOT NULL,
date DATE NOT NULL,
total_sessions INT(11) DEFAULT 0,
avg_response_time DECIMAL(6,2),
avg_rating DECIMAL(3,2),
avg_quality_score DECIMAL(3,2),
first_response_time DECIMAL(6,2),
resolution_rate DECIMAL(5,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (performance_id),
UNIQUE KEY agent_date (agent_id, date),
KEY agent_id (agent_id),
KEY date (date)
);
2.2 数据库操作类实现
创建数据库操作类,封装所有数据库交互逻辑:
<?php
/**
* 客服会话数据库操作类
*/
class ChatSessionDB {
private $wpdb;
private $sessions_table;
private $messages_table;
private $quality_table;
private $performance_table;
public function __construct() {
global $wpdb;
$this->wpdb = $wpdb;
$this->sessions_table = $wpdb->prefix . 'chat_sessions';
$this->messages_table = $wpdb->prefix . 'chat_messages';
$this->quality_table = $wpdb->prefix . 'chat_quality';
$this->performance_table = $wpdb->prefix . 'agent_performance';
}
/**
* 创建新会话
*/
public function create_session($data) {
$defaults = array(
'session_key' => uniqid('chat_'),
'start_time' => current_time('mysql'),
'status' => 'active'
);
$data = wp_parse_args($data, $defaults);
$result = $this->wpdb->insert(
$this->sessions_table,
$data,
array('%s', '%d', '%s', '%s', '%d', '%s', '%s', '%s', '%d', '%s', '%d')
);
if ($result) {
return $this->wpdb->insert_id;
}
return false;
}
/**
* 添加会话消息
*/
public function add_message($session_id, $sender_type, $content, $message_type = 'text', $media_data = array()) {
$data = array(
'session_id' => $session_id,
'sender_type' => $sender_type,
'message_type' => $message_type,
'content' => $content,
'sent_time' => current_time('mysql')
);
// 处理媒体文件
if (!empty($media_data)) {
$data['media_url'] = isset($media_data['url']) ? $media_data['url'] : '';
$data['file_name'] = isset($media_data['name']) ? $media_data['name'] : '';
$data['file_size'] = isset($media_data['size']) ? $media_data['size'] : 0;
}
// 如果是客服发送的消息,记录客服ID
if ($sender_type === 'agent' && is_user_logged_in()) {
$data['sender_id'] = get_current_user_id();
}
$result = $this->wpdb->insert(
$this->messages_table,
$data,
array('%d', '%s', '%d', '%s', '%s', '%s', '%s', '%d', '%s')
);
return $result ? $this->wpdb->insert_id : false;
}
/**
* 获取会话消息
*/
public function get_session_messages($session_id, $limit = 100, $offset = 0) {
$query = $this->wpdb->prepare(
"SELECT * FROM {$this->messages_table}
WHERE session_id = %d
ORDER BY sent_time ASC
LIMIT %d OFFSET %d",
$session_id, $limit, $offset
);
return $this->wpdb->get_results($query);
}
/**
* 更新会话状态
*/
public function update_session_status($session_id, $status, $end_time = null) {
$data = array('status' => $status);
if ($end_time) {
$data['end_time'] = $end_time;
// 计算会话时长
$session = $this->get_session($session_id);
if ($session && $session->start_time) {
$start = strtotime($session->start_time);
$end = strtotime($end_time);
$data['duration'] = $end - $start;
}
}
return $this->wpdb->update(
$this->sessions_table,
$data,
array('session_id' => $session_id),
array('%s', '%s', '%d'),
array('%d')
);
}
/**
* 添加质检记录
*/
public function add_quality_evaluation($session_id, $scores, $evaluator_id = null, $notes = '') {
// 计算总分
$total = 0;
$count = 0;
foreach ($scores as $score) {
if (!is_null($score)) {
$total += $score;
$count++;
}
}
$overall_score = $count > 0 ? round($total / $count, 2) : 0;
$data = array(
'session_id' => $session_id,
'evaluator_id' => $evaluator_id ?: get_current_user_id(),
'evaluation_time' => current_time('mysql'),
'overall_score' => $overall_score,
'notes' => $notes
);
// 添加各项分数
$score_fields = array(
'response_time_score',
'professionalism_score',
'problem_solving_score',
'communication_score'
);
foreach ($score_fields as $field) {
if (isset($scores[$field])) {
$data[$field] = $scores[$field];
}
}
// 关键词分析(简化版,实际应用中可能需要更复杂的NLP处理)
if (isset($scores['positive_keywords'])) {
$data['positive_keywords'] = is_array($scores['positive_keywords'])
? implode(',', $scores['positive_keywords'])
: $scores['positive_keywords'];
}
if (isset($scores['negative_keywords'])) {
$data['negative_keywords'] = is_array($scores['negative_keywords'])
? implode(',', $scores['negative_keywords'])
: $scores['negative_keywords'];
}
return $this->wpdb->insert(
$this->quality_table,
$data,
array('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%f', '%s', '%s', '%s', '%s')
);
}
/**
* 获取客服绩效数据
*/
public function get_agent_performance($agent_id, $start_date, $end_date) {
$query = $this->wpdb->prepare(
"SELECT * FROM {$this->performance_table}
WHERE agent_id = %d
AND date BETWEEN %s AND %s
ORDER BY date ASC",
$agent_id, $start_date, $end_date
);
return $this->wpdb->get_results($query);
}
/**
* 统计会话数据
*/
public function get_session_stats($filters = array()) {
$where = array('1=1');
$params = array();
// 时间筛选
if (!empty($filters['start_date'])) {
$where[] = "start_time >= %s";
$params[] = $filters['start_date'];
}
if (!empty($filters['end_date'])) {
$where[] = "start_time <= %s";
$params[] = $filters['end_date'] . ' 23:59:59';
}
// 客服筛选
if (!empty($filters['agent_id'])) {
$where[] = "agent_id = %d";
$params[] = $filters['agent_id'];
}
// 状态筛选
if (!empty($filters['status'])) {
$where[] = "status = %s";
$params[] = $filters['status'];
}
$where_clause = implode(' AND ', $where);
// 基础统计
$query = $this->wpdb->prepare(
"SELECT
COUNT(*) as total_sessions,
AVG(duration) as avg_duration,
AVG(rating) as avg_rating,
SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END) as closed_sessions,
SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_sessions
FROM {$this->sessions_table}
WHERE {$where_clause}",
$params
);
return $this->wpdb->get_row($query);
}
}
?>
三、WordPress插件开发
3.1 插件基础结构
创建插件主文件 chat-archive-analyzer.php:
<?php
/**
* Plugin Name: 在线客服会话存档与质检分析系统
* Plugin URI: https://yourwebsite.com/
* Description: 在WordPress中集成在线客服会话存档与质检分析功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: chat-archive-analyzer
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CHAT_ARCHIVE_VERSION', '1.0.0');
define('CHAT_ARCHIVE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CHAT_ARCHIVE_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类
spl_autoload_register(function ($class) {
$prefix = 'ChatArchive\';
$base_dir = CHAT_ARCHIVE_PLUGIN_DIR . 'includes/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
// 初始化插件
class ChatArchiveAnalyzer {
private static $instance = null;
private $db;
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'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('plugins_loaded', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
// AJAX处理
add_action('wp_ajax_chat_archive_action', array($this, 'handle_ajax_request'));
add_action('wp_ajax_nopriv_chat_archive_action', array($this, 'handle_ajax_request'));
// 短代码
add_shortcode('chat_session_archive', array($this, 'shortcode_session_archive'));
add_shortcode('chat_analytics_dashboard', array($this, 'shortcode_analytics_dashboard'));
}
public function activate() {
require_once CHAT_ARCHIVE_PLUGIN_DIR . 'includes/class-installer.php';
ChatArchiveInstaller::install();
// 创建默认选项
$default_options = array(
'auto_archive' => true,
'retention_days' => 365,
'quality_auto_evaluation' => false,
'enable_realtime_monitoring' => true,
'dashboard_access_roles' => array('administrator', 'editor')
);
add_option('chat_archive_settings', $default_options);
}
public function deactivate() {
// 清理临时数据
wp_clear_scheduled_hook('chat_archive_daily_maintenance');
}
public function init() {
// 初始化数据库类
$this->db = new ChatSessionDB();
// 加载文本域
load_plugin_textdomain('chat-archive-analyzer', false, dirname(plugin_basename(__FILE__)) . '/languages');
// 初始化API
if (class_exists('ChatArchiveAPI')) {
new ChatArchiveAPI();
}
// 初始化第三方集成
$this->init_third_party_integrations();
}
private function init_third_party_integrations() {
// 检查并加载可用的第三方客服系统集成
$integrations_dir = CHAT_ARCHIVE_PLUGIN_DIR . 'includes/integrations/';
if (file_exists($integrations_dir)) {
$integrations = glob($integrations_dir . '*.php');
foreach ($integrations as $integration_file) {
$integration_name = basename($integration_file, '.php');
// 检查是否启用了该集成
$settings = get_option('chat_archive_settings', array());
$enabled_integrations = isset($settings['enabled_integrations']) ? $settings['enabled_integrations'] : array();
if (in_array($integration_name, $enabled_integrations) || empty($enabled_integrations)) {
require_once $integration_file;
$class_name = 'ChatArchive\Integrations\' . ucfirst($integration_name);
if (class_exists($class_name)) {
new $class_name();
}
}
}
}
}
public function add_admin_menu() {
// 主菜单
add_menu_page(
__('客服会话存档', 'chat-archive-analyzer'),
__('客服会话', 'chat-archive-analyzer'),
'manage_options',
'chat-archive',
array($this, 'render_admin_page'),
'dashicons-format-chat',
30
);
// 子菜单
add_submenu_page(
'chat-archive',
__('会话存档', 'chat-archive-analyzer'),
__('会话存档', 'chat-archive-analyzer'),
'manage_options',
'chat-archive-sessions',
array($this, 'render_sessions_page')
);
add_submenu_page(
'chat-archive',
__('质检分析', 'chat-archive-analyzer'),
__('质检分析', 'chat-archive-analyzer'),
'manage_options',
'chat-archive-quality',
array($this, 'render_quality_page')
);
add_submenu_page(
'chat-archive',
__('数据分析', 'chat-archive-analyzer'),
__('数据分析', 'chat-archive-analyzer'),
'manage_options',
'chat-archive-analytics',
array($this, 'render_analytics_page')
);
add_submenu_page(
'chat-archive',
__('实时监控', 'chat-archive-analyzer'),
__('实时监控', 'chat-archive-analyzer'),
'manage_options',
'chat-archive-monitor',
array($this, 'render_monitor_page')
);
add_submenu_page(
'chat-archive',
__('设置', 'chat-archive-analyzer'),
__('设置', 'chat-archive-analyzer'),
'manage_options',
'chat-archive-settings',
array($this, 'render_settings_page')
);
}
public function render_admin_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/dashboard.php';
}
public function render_sessions_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/sessions.php';
}
public function render_quality_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/quality.php';
}
public function render_analytics_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/analytics.php';
}
public function render_monitor_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/monitor.php';
}
public function render_settings_page() {
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/admin/settings.php';
}
public function enqueue_admin_scripts($hook) {
// 只在插件页面加载
if (strpos($hook, 'chat-archive') === false) {
return;
}
// CSS
wp_enqueue_style(
'chat-archive-admin',
CHAT_ARCHIVE_PLUGIN_URL . 'assets/css/admin.css',
array(),
CHAT_ARCHIVE_VERSION
);
// JavaScript
wp_enqueue_script(
'chat-archive-admin',
CHAT_ARCHIVE_PLUGIN_URL . 'assets/js/admin.js',
array('jquery', 'jquery-ui-datepicker', 'chart-js'),
CHAT_ARCHIVE_VERSION,
true
);
// 加载Chart.js
wp_enqueue_script(
'chart-js',
'https://cdn.jsdelivr.net/npm/chart.js',
array(),
'3.7.0',
true
);
// 本地化脚本
wp_localize_script('chat-archive-admin', 'chatArchive', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('chat_archive_nonce'),
'strings' => array(
'loading' => __('加载中...', 'chat-archive-analyzer'),
'error' => __('发生错误', 'chat-archive-analyzer'),
'confirm_delete' => __('确定要删除这条记录吗?', 'chat-archive-analyzer')
)
));
}
public function enqueue_frontend_scripts() {
// 前端样式和脚本(用于短代码)
if (is_page() || is_single()) {
global $post;
if (has_shortcode($post->post_content, 'chat_session_archive') ||
has_shortcode($post->post_content, 'chat_analytics_dashboard')) {
wp_enqueue_style(
'chat-archive-frontend',
CHAT_ARCHIVE_PLUGIN_URL . 'assets/css/frontend.css',
array(),
CHAT_ARCHIVE_VERSION
);
wp_enqueue_script(
'chat-archive-frontend',
CHAT_ARCHIVE_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
CHAT_ARCHIVE_VERSION,
true
);
}
}
}
public function handle_ajax_request() {
// 验证nonce
if (!check_ajax_referer('chat_archive_nonce', 'nonce', false)) {
wp_die(__('安全验证失败', 'chat-archive-analyzer'), 403);
}
$action = isset($_POST['action_type']) ? sanitize_text_field($_POST['action_type']) : '';
switch ($action) {
case 'get_sessions':
$this->ajax_get_sessions();
break;
case 'get_session_detail':
$this->ajax_get_session_detail();
break;
case 'add_quality_evaluation':
$this->ajax_add_quality_evaluation();
break;
case 'get_analytics_data':
$this->ajax_get_analytics_data();
break;
case 'export_sessions':
$this->ajax_export_sessions();
break;
default:
wp_send_json_error(array('message' => __('未知操作', 'chat-archive-analyzer')));
}
}
private function ajax_get_sessions() {
// 验证权限
if (!current_user_can('manage_options')) {
wp_send_json_error(array('message' => __('权限不足', 'chat-archive-analyzer')));
}
$page = isset($_POST['page']) ? intval($_POST['page']) : 1;
$per_page = isset($_POST['per_page']) ? intval($_POST['per_page']) : 20;
$filters = isset($_POST['filters']) ? $_POST['filters'] : array();
// 清理过滤条件
$clean_filters = array();
if (isset($filters['start_date'])) {
$clean_filters['start_date'] = sanitize_text_field($filters['start_date']);
}
if (isset($filters['end_date'])) {
$clean_filters['end_date'] = sanitize_text_field($filters['end_date']);
}
if (isset($filters['agent_id'])) {
$clean_filters['agent_id'] = intval($filters['agent_id']);
}
if (isset($filters['status'])) {
$clean_filters['status'] = sanitize_text_field($filters['status']);
}
if (isset($filters['search'])) {
$clean_filters['search'] = sanitize_text_field($filters['search']);
}
// 获取会话数据
$sessions = $this->db->get_sessions($clean_filters, $page, $per_page);
$total = $this->db->count_sessions($clean_filters);
wp_send_json_success(array(
'sessions' => $sessions,
'total' => $total,
'total_pages' => ceil($total / $per_page),
'current_page' => $page
));
}
public function shortcode_session_archive($atts) {
// 检查用户权限
if (!is_user_logged_in()) {
return '<p>' . __('请登录后查看会话记录', 'chat-archive-analyzer') . '</p>';
}
$atts = shortcode_atts(array(
'agent_id' => get_current_user_id(),
'limit' => 10,
'show_search' => true
), $atts, 'chat_session_archive');
ob_start();
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/frontend/session-archive.php';
return ob_get_clean();
}
public function shortcode_analytics_dashboard($atts) {
// 检查用户权限
$user = wp_get_current_user();
$allowed_roles = array('administrator', 'editor', 'shop_manager');
if (!array_intersect($allowed_roles, $user->roles)) {
return '<p>' . __('您没有权限查看此页面', 'chat-archive-analyzer') . '</p>';
}
$atts = shortcode_atts(array(
'period' => 'month',
'show_agents' => true,
'show_trends' => true
), $atts, 'chat_analytics_dashboard');
ob_start();
include CHAT_ARCHIVE_PLUGIN_DIR . 'templates/frontend/analytics-dashboard.php';
return ob_get_clean();
}
}
// 启动插件
ChatArchiveAnalyzer::get_instance();
?>
### 3.2 安装器类实现
创建 `includes/class-installer.php`:
<?php
namespace ChatArchive;
class Installer {
public static function install() {
self::create_tables();
self::create_roles();
self::schedule_events();
}
private static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 这里包含之前设计的SQL表创建语句
require_once CHAT_ARCHIVE_PLUGIN_DIR . 'includes/schema.php';
dbDelta($sql);
}
private static function create_roles() {
// 添加客服主管角色
add_role('chat_supervisor', __('客服主管', 'chat-archive-analyzer'), array(
'read' => true,
'edit_posts' => true,
'delete_posts' => true,
'manage_chat_sessions' => true,
'evaluate_chat_quality' => true,
'view_chat_analytics' => true
));
// 添加客服角色
add_role('chat_agent', __('客服专员', 'chat-archive-analyzer'), array(
'read' => true,
'edit_posts' => false,
'view_own_chat_sessions' => true,
'view_own_performance' => true
));
// 为管理员添加自定义权限
$admin_role = get_role('administrator');
if ($admin_role) {
$admin_role->add_cap('manage_chat_sessions');
$admin_role->add_cap('evaluate_chat_quality');
$admin_role->add_cap('view_chat_analytics');
$admin_role->add_cap('configure_chat_system');
}
}
private static function schedule_events() {
if (!wp_next_scheduled('chat_archive_daily_maintenance')) {
wp_schedule_event(time(), 'daily', 'chat_archive_daily_maintenance');
}
if (!wp_next_scheduled('chat_archive_hourly_processing')) {
wp_schedule_event(time(), 'hourly', 'chat_archive_hourly_processing');
}
}
}
?>
---
## 四、前端界面与用户体验
### 4.1 管理界面模板
创建 `templates/admin/sessions.php`:
<div class="wrap chat-archive-wrapper">
<h1><?php _e('客服会话存档', 'chat-archive-analyzer'); ?></h1>
<!-- 过滤条件 -->
<div class="chat-filter-section">
<form id="chat-session-filter" method="get">
<input type="hidden" name="page" value="chat-archive-sessions">
<div class="filter-row">
<div class="filter-group">
<label for="filter-date-start"><?php _e('开始日期', 'chat-archive-analyzer'); ?></label>
<input type="date" id="filter-date-start" name="date_start" class="regular-text">
</div>
<div class="filter-group">
<label for="filter-date-end"><?php _e('结束日期', 'chat-archive-analyzer'); ?></label>
<input type="date" id="filter-date-end" name="date_end" class="regular-text">
</div>
<div class="filter-group">
<label for="filter-agent"><?php _e('客服人员', 'chat-archive-analyzer'); ?></label>
<select id="filter-agent" name="agent_id">
<option value=""><?php _e('所有客服', 'chat-archive-analyzer'); ?></option>
<?php
$agents = get_users(array('role__in' => array('chat_agent', 'administrator', 'editor')));
foreach ($agents as $agent) {
echo '<option value="' . $agent->ID . '">' . $agent->display_name . '</option>';
}
?>
</select>
</div>
<div class="filter-group">
<label for="filter-status"><?php _e('会话状态', 'chat-archive-analyzer'); ?></label>
<select id="filter-status" name="status">
<option value=""><?php _e('所有状态', 'chat-archive-analyzer'); ?></option>
<option value="active"><?php _e('进行中', 'chat-archive-analyzer'); ?></option>
<option value="closed"><?php _e('已结束', 'chat-archive-analyzer'); ?></option>
<option value="transferred"><?php _e('已转接', 'chat-archive-analyzer'); ?></option>
</select>
</div>
<div class="filter-group">
<label for="filter-search"><?php _e('关键词搜索', 'chat-archive-analyzer'); ?></label>
<input type="text" id="filter-search" name="search" placeholder="<?php _e('客户姓名、邮箱或会话内容', 'chat-archive-analyzer'); ?>">
</div>
<div class="filter-actions">
<button type="submit" class="button button-primary"><?php _e('筛选', 'chat-archive-analyzer'); ?></button>
<button type="button" id="reset-filters" class="button"><?php _e('重置', 'chat-archive-analyzer'); ?></button>
</div>
</div>
</form>
</div>
<!-- 会话列表 -->
<div class="chat-sessions-list">
<div class="tablenav top">
<div class="alignleft actions">
<select id="bulk-action-selector">
<option value=""><?php _e('批量操作', 'chat-archive-analyzer'); ?></option>
<option value="export"><?php _e('导出选中', 'chat-archive-analyzer'); ?></option>
<option value="delete"><?php _e('删除选中', 'chat-archive-analyzer'); ?></option>
</select>
<button id="do-bulk-action" class="button"><?php _e('应用', 'chat-archive-analyzer'); ?></button>
</div>
<div class="tablenav-pages">
<span class="displaying-num"></span>
<span class="pagination-links">
<button class="button first-page" disabled><?php _e('首页', 'chat-archive-analyzer'); ?></button>
<button class="button prev-page" disabled><?php _e('上一页', 'chat-archive-analyzer'); ?></button>
<span class="paging-input">
<input type="text" class="current-page" size="2" value="1">
<?php _e('共', 'chat-archive-analyzer'); ?> <span class="total-pages">1</span> <?php _e('页', 'chat-archive-analyzer'); ?>
