文章目录[隐藏]
手把手教程:为WordPress网站添加智能在线客服系统及常用互联网小工具
引言:为什么你的网站需要智能客服系统?
在当今数字化时代,网站已不仅仅是企业展示信息的平台,更是与客户互动、提供服务和促成交易的重要渠道。据统计,拥有在线客服系统的网站转化率平均提高30%以上,客户满意度提升40%。然而,许多WordPress网站所有者面临一个共同困境:如何在不依赖昂贵第三方服务的情况下,为网站添加功能完善的智能客服系统?
本教程将手把手教你通过WordPress代码二次开发,实现一个集智能客服、常见工具和小功能于一体的综合解决方案。无需昂贵的插件费用,完全自主控制,且能根据你的具体需求灵活定制。
第一部分:准备工作与环境搭建
1.1 开发环境要求
在开始之前,请确保你的开发环境满足以下要求:
- WordPress 5.0或更高版本
- PHP 7.2或更高版本(推荐7.4+)
- MySQL 5.6或更高版本
- 基本的HTML、CSS、JavaScript和PHP知识
- 代码编辑器(如VS Code、Sublime Text等)
- 本地开发环境(如XAMPP、MAMP或Local by Flywheel)
1.2 创建子主题(保护核心文件)
为了避免主题更新时丢失自定义代码,我们首先创建一个子主题:
- 在WordPress的
wp-content/themes/目录下创建新文件夹,命名为my-custom-theme - 在该文件夹中创建
style.css文件,添加以下内容:
/*
Theme Name: My Custom Theme
Template: twentytwentyone // 根据你的父主题修改
Version: 1.0.0
Description: 自定义主题,用于添加智能客服系统
*/
- 创建
functions.php文件,添加以下代码:
<?php
// 子主题functions.php文件
add_action('wp_enqueue_scripts', 'my_custom_theme_enqueue_styles');
function my_custom_theme_enqueue_styles() {
// 加载父主题样式
wp_enqueue_style('parent-style', get_template_directory_uri() . '/style.css');
// 加载子主题样式
wp_enqueue_style('child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style'));
}
?>
- 在WordPress后台激活这个子主题
第二部分:构建基础在线客服系统
2.1 设计客服系统界面
首先,我们创建客服系统的基础HTML结构和CSS样式。在子主题目录下创建custom-chat.php文件:
<?php
/**
* 智能在线客服系统界面
*/
?>
<div id="smart-customer-service" class="smart-cs-container">
<!-- 客服系统触发按钮 -->
<button id="cs-toggle-btn" class="cs-toggle-btn">
<span class="cs-icon">💬</span>
<span class="cs-text">在线客服</span>
</button>
<!-- 客服主界面 -->
<div id="cs-main-panel" class="cs-main-panel">
<div class="cs-header">
<h3>智能在线客服</h3>
<button id="cs-close-btn" class="cs-close-btn">×</button>
</div>
<div class="cs-body">
<!-- 消息显示区域 -->
<div id="cs-messages" class="cs-messages">
<div class="cs-welcome-msg">
<p>您好!我是智能客服助手,有什么可以帮您?</p>
<p>您也可以尝试以下常见问题:</p>
<div class="cs-quick-questions">
<button class="cs-quick-btn" data-question="产品价格是多少?">产品价格</button>
<button class="cs-quick-btn" data-question="如何下单购买?">购买流程</button>
<button class="cs-quick-btn" data-question="售后服务政策">售后服务</button>
</div>
</div>
</div>
<!-- 消息输入区域 -->
<div class="cs-input-area">
<textarea id="cs-user-input" placeholder="请输入您的问题..." rows="2"></textarea>
<button id="cs-send-btn" class="cs-send-btn">发送</button>
</div>
<!-- 功能扩展区域 -->
<div class="cs-extensions">
<button class="cs-ext-btn" data-action="upload">
<span>📎</span> 上传文件
</button>
<button class="cs-ext-btn" data-action="screenshot">
<span>📷</span> 屏幕截图
</button>
<button class="cs-ext-btn" data-action="voice">
<span>🎤</span> 语音输入
</button>
</div>
</div>
</div>
</div>
接下来,创建CSS样式文件custom-chat.css:
/* 智能客服系统样式 */
.smart-cs-container {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 999999;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
}
/* 触发按钮样式 */
.cs-toggle-btn {
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
color: white;
border: none;
border-radius: 50px;
padding: 12px 24px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 15px rgba(106, 17, 203, 0.3);
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
}
.cs-toggle-btn:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(106, 17, 203, 0.4);
}
.cs-icon {
font-size: 20px;
}
/* 客服主面板 */
.cs-main-panel {
position: absolute;
bottom: 70px;
right: 0;
width: 350px;
height: 500px;
background: white;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
display: none;
flex-direction: column;
overflow: hidden;
}
.cs-main-panel.active {
display: flex;
}
/* 面板头部 */
.cs-header {
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
color: white;
padding: 15px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.cs-header h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
}
.cs-close-btn {
background: none;
border: none;
color: white;
font-size: 24px;
cursor: pointer;
line-height: 1;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background 0.2s;
}
.cs-close-btn:hover {
background: rgba(255, 255, 255, 0.2);
}
/* 消息区域 */
.cs-body {
flex: 1;
display: flex;
flex-direction: column;
padding: 0;
}
.cs-messages {
flex: 1;
padding: 20px;
overflow-y: auto;
background: #f8f9fa;
}
.cs-welcome-msg {
background: white;
border-radius: 10px;
padding: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
margin-bottom: 20px;
}
.cs-welcome-msg p {
margin: 0 0 10px 0;
color: #333;
line-height: 1.5;
}
.cs-quick-questions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.cs-quick-btn {
background: #f0f4ff;
border: 1px solid #d0d7ff;
border-radius: 20px;
padding: 6px 12px;
font-size: 13px;
color: #4a6bff;
cursor: pointer;
transition: all 0.2s;
}
.cs-quick-btn:hover {
background: #4a6bff;
color: white;
}
/* 消息气泡 */
.cs-message {
margin-bottom: 15px;
max-width: 80%;
}
.cs-message.user {
margin-left: auto;
}
.cs-message.bot {
margin-right: auto;
}
.message-bubble {
padding: 10px 15px;
border-radius: 18px;
line-height: 1.4;
word-wrap: break-word;
}
.user .message-bubble {
background: #4a6bff;
color: white;
border-bottom-right-radius: 4px;
}
.bot .message-bubble {
background: white;
color: #333;
border: 1px solid #e0e0e0;
border-bottom-left-radius: 4px;
}
/* 输入区域 */
.cs-input-area {
border-top: 1px solid #e0e0e0;
padding: 15px;
background: white;
}
#cs-user-input {
width: 100%;
border: 1px solid #ddd;
border-radius: 8px;
padding: 10px 15px;
font-size: 14px;
resize: none;
font-family: inherit;
margin-bottom: 10px;
}
#cs-user-input:focus {
outline: none;
border-color: #4a6bff;
box-shadow: 0 0 0 2px rgba(74, 107, 255, 0.1);
}
.cs-send-btn {
background: #4a6bff;
color: white;
border: none;
border-radius: 8px;
padding: 10px 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
width: 100%;
transition: background 0.2s;
}
.cs-send-btn:hover {
background: #3a5bef;
}
/* 扩展功能区域 */
.cs-extensions {
display: flex;
gap: 10px;
padding: 10px 15px;
background: #f8f9fa;
border-top: 1px solid #e0e0e0;
}
.cs-ext-btn {
flex: 1;
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 8px;
font-size: 12px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
transition: all 0.2s;
}
.cs-ext-btn:hover {
border-color: #4a6bff;
color: #4a6bff;
}
.cs-ext-btn span {
font-size: 16px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.cs-main-panel {
width: calc(100vw - 40px);
height: 70vh;
right: 20px;
bottom: 80px;
}
.smart-cs-container {
bottom: 10px;
right: 10px;
}
}
2.2 实现客服系统JavaScript功能
创建JavaScript文件custom-chat.js:
/**
* 智能在线客服系统JavaScript功能
*/
document.addEventListener('DOMContentLoaded', function() {
// 获取DOM元素
const csToggleBtn = document.getElementById('cs-toggle-btn');
const csMainPanel = document.getElementById('cs-main-panel');
const csCloseBtn = document.getElementById('cs-close-btn');
const csUserInput = document.getElementById('cs-user-input');
const csSendBtn = document.getElementById('cs-send-btn');
const csMessages = document.getElementById('cs-messages');
const csQuickBtns = document.querySelectorAll('.cs-quick-btn');
const csExtBtns = document.querySelectorAll('.cs-ext-btn');
// 客服系统状态
let isChatOpen = false;
let chatHistory = [];
// 初始化
initChatSystem();
function initChatSystem() {
// 加载历史记录
loadChatHistory();
// 绑定事件
csToggleBtn.addEventListener('click', toggleChatPanel);
csCloseBtn.addEventListener('click', closeChatPanel);
csSendBtn.addEventListener('click', sendMessage);
csUserInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
// 快速问题按钮
csQuickBtns.forEach(btn => {
btn.addEventListener('click', function() {
const question = this.getAttribute('data-question');
csUserInput.value = question;
sendMessage();
});
});
// 扩展功能按钮
csExtBtns.forEach(btn => {
btn.addEventListener('click', function() {
const action = this.getAttribute('data-action');
handleExtensionAction(action);
});
});
// 自动调整输入框高度
csUserInput.addEventListener('input', autoResizeTextarea);
// 点击外部关闭面板
document.addEventListener('click', function(e) {
if (isChatOpen &&
!csMainPanel.contains(e.target) &&
!csToggleBtn.contains(e.target)) {
closeChatPanel();
}
});
}
// 切换聊天面板
function toggleChatPanel() {
isChatOpen = !isChatOpen;
if (isChatOpen) {
csMainPanel.classList.add('active');
csUserInput.focus();
} else {
csMainPanel.classList.remove('active');
}
}
// 关闭聊天面板
function closeChatPanel() {
isChatOpen = false;
csMainPanel.classList.remove('active');
}
// 发送消息
function sendMessage() {
const message = csUserInput.value.trim();
if (!message) return;
// 添加用户消息
addMessage(message, 'user');
// 清空输入框
csUserInput.value = '';
autoResizeTextarea();
// 保存到历史记录
saveToHistory(message, 'user');
// 模拟AI回复(实际应调用后端API)
setTimeout(() => {
const response = generateAIResponse(message);
addMessage(response, 'bot');
saveToHistory(response, 'bot');
}, 1000);
}
// 添加消息到界面
function addMessage(text, sender) {
const messageDiv = document.createElement('div');
messageDiv.className = `cs-message ${sender}`;
const bubbleDiv = document.createElement('div');
bubbleDiv.className = 'message-bubble';
bubbleDiv.textContent = text;
messageDiv.appendChild(bubbleDiv);
csMessages.appendChild(messageDiv);
// 滚动到底部
csMessages.scrollTop = csMessages.scrollHeight;
}
// 生成AI回复(简化版)
function generateAIResponse(userMessage) {
const responses = {
'价格': '我们的产品价格根据配置不同而有所差异,基础版为¥299/月,专业版为¥599/月,企业版需要定制报价。',
'购买': '购买流程非常简单:1) 选择套餐 2) 注册账号 3) 在线支付 4) 开通服务。全程只需5分钟!',
'售后': '我们提供7天无理由退款,30天免费更换,以及终身技术支持。具体政策请查看售后服务页面。',
'默认': '我理解您的问题了。为了给您更准确的回答,您可以联系我们的专业客服人员,或访问我们的帮助中心查看详细文档。'
};
let response = responses['默认'];
// 简单关键词匹配
if (userMessage.includes('价格') || userMessage.includes('多少钱')) {
response = responses['价格'];
} else if (userMessage.includes('购买') || userMessage.includes('下单')) {
response = responses['购买'];
} else if (userMessage.includes('售后') || userMessage.includes('服务')) {
response = responses['售后'];
}
return response;
}
// 处理扩展功能
function handleExtensionAction(action) {
switch(action) {
case 'upload':
triggerFileUpload();
break;
case 'screenshot':
takeScreenshot();
break;
case 'voice':
startVoiceInput();
break;
}
}
// 触发文件上传
function triggerFileUpload() {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*,.pdf,.doc,.docx';
input.onchange = function(e) {
const file = e.target.files[0];
if (file) {
addMessage(`已选择文件: ${file.name} (${formatFileSize(file.size)})`, 'user');
// 这里可以添加上传逻辑
}
};
input.click();
}
// 屏幕截图功能
function takeScreenshot() {
addMessage('正在准备截图功能...', 'bot');
// 实际实现需要使用截图API或库
}
// 语音输入功能
function startVoiceInput() {
if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
addMessage('您的浏览器不支持语音输入功能', 'bot');
return;
}
addMessage('正在聆听...请说话', 'bot');
// 实际实现需要语音识别API
2.3 实现后端处理与数据存储
创建PHP处理文件chat-handler.php:
<?php
/**
* 智能客服系统后端处理
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 添加AJAX处理端点
add_action('wp_ajax_submit_chat_message', 'handle_chat_message');
add_action('wp_ajax_nopriv_submit_chat_message', 'handle_chat_message');
function handle_chat_message() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'chat_nonce')) {
wp_die('安全验证失败');
}
$user_message = sanitize_text_field($_POST['message']);
$user_id = get_current_user_id();
$session_id = sanitize_text_field($_POST['session_id']);
// 保存用户消息到数据库
save_chat_message($user_id, $session_id, $user_message, 'user');
// 获取AI回复
$ai_response = get_ai_response($user_message);
// 保存AI回复到数据库
save_chat_message($user_id, $session_id, $ai_response, 'bot');
// 返回响应
wp_send_json_success(array(
'response' => $ai_response,
'timestamp' => current_time('mysql')
));
}
// 保存聊天消息到数据库
function save_chat_message($user_id, $session_id, $message, $sender) {
global $wpdb;
$table_name = $wpdb->prefix . 'chat_messages';
$wpdb->insert(
$table_name,
array(
'user_id' => $user_id,
'session_id' => $session_id,
'message' => $message,
'sender' => $sender,
'created_at' => current_time('mysql')
),
array('%d', '%s', '%s', '%s', '%s')
);
}
// 获取AI回复(可扩展集成真实AI服务)
function get_ai_response($message) {
// 预定义回复规则
$responses = array(
'价格' => '我们的产品提供多种套餐:基础版(¥299/月)、专业版(¥599/月)、企业版(定制报价)。所有套餐均包含基础功能和技术支持。',
'购买' => '购买流程:1) 选择套餐 2) 创建账户 3) 完成支付 4) 开通服务。支持支付宝、微信支付和银行转账。',
'售后' => '售后服务包括:7天无理由退款、30天质量问题换新、终身技术咨询。工作时间:周一至周五 9:00-18:00。',
'联系' => '您可以通过以下方式联系我们:电话:400-xxx-xxxx,邮箱:support@example.com,或直接在聊天中留言。',
'功能' => '我们的系统主要功能包括:智能客服、工单管理、知识库、数据分析报表和API接口。'
);
// 关键词匹配
foreach ($responses as $keyword => $response) {
if (strpos($message, $keyword) !== false) {
return $response;
}
}
// 默认回复(可集成第三方AI API)
return '感谢您的咨询!我已经记录您的问题,稍后会有专业客服人员为您详细解答。您也可以尝试以下关键词获取快速回答:价格、购买、售后、联系、功能。';
}
// 创建聊天记录数据库表
function create_chat_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'chat_messages';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) DEFAULT 0,
session_id varchar(100) NOT NULL,
message text NOT NULL,
sender varchar(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY session_id (session_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// 注册激活钩子
register_activation_hook(__FILE__, 'create_chat_tables');
第三部分:集成常用互联网小工具
3.1 网站访问统计工具
创建访问统计功能文件website-stats.php:
<?php
/**
* 网站访问统计工具
*/
// 跟踪访问统计
function track_website_visits() {
if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
return;
}
global $wpdb;
$table_name = $wpdb->prefix . 'website_stats';
$ip_address = $_SERVER['REMOTE_ADDR'];
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$page_url = $_SERVER['REQUEST_URI'];
$referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
// 检查是否已记录(防止重复记录)
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name
WHERE ip_address = %s
AND page_url = %s
AND DATE(visited_at) = CURDATE()
LIMIT 1",
$ip_address, $page_url
));
if (!$existing) {
$wpdb->insert(
$table_name,
array(
'ip_address' => $ip_address,
'user_agent' => $user_agent,
'page_url' => $page_url,
'referrer' => $referrer,
'visited_at' => current_time('mysql')
)
);
}
}
add_action('wp', 'track_website_visits');
// 创建统计表
function create_stats_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'website_stats';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
ip_address varchar(45) NOT NULL,
user_agent text NOT NULL,
page_url varchar(500) NOT NULL,
referrer varchar(500) DEFAULT '',
visited_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY visited_at (visited_at),
KEY page_url (page_url(100))
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// 获取统计数据的短代码
function display_website_stats($atts) {
global $wpdb;
$table_name = $wpdb->prefix . 'website_stats';
$atts = shortcode_atts(array(
'period' => 'today',
'type' => 'visits'
), $atts);
$where = '';
switch ($atts['period']) {
case 'today':
$where = "WHERE DATE(visited_at) = CURDATE()";
break;
case 'week':
$where = "WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
break;
case 'month':
$where = "WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)";
break;
}
if ($atts['type'] === 'visits') {
$count = $wpdb->get_var("SELECT COUNT(DISTINCT ip_address) FROM $table_name $where");
return "<div class='stats-widget'><h4>独立访客</h4><p class='stats-number'>$count</p></div>";
} elseif ($atts['type'] === 'pageviews') {
$count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where");
return "<div class='stats-widget'><h4>页面浏览</h4><p class='stats-number'>$count</p></div>";
}
}
add_shortcode('website_stats', 'display_website_stats');
// 添加统计小工具到仪表盘
function add_stats_dashboard_widget() {
wp_add_dashboard_widget(
'website_stats_widget',
'网站访问统计',
'display_dashboard_stats'
);
}
add_action('wp_dashboard_setup', 'add_stats_dashboard_widget');
function display_dashboard_stats() {
global $wpdb;
$table_name = $wpdb->prefix . 'website_stats';
$today_visits = $wpdb->get_var(
"SELECT COUNT(DISTINCT ip_address)
FROM $table_name
WHERE DATE(visited_at) = CURDATE()"
);
$week_visits = $wpdb->get_var(
"SELECT COUNT(DISTINCT ip_address)
FROM $table_name
WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"
);
$popular_pages = $wpdb->get_results(
"SELECT page_url, COUNT(*) as views
FROM $table_name
WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY page_url
ORDER BY views DESC
LIMIT 5"
);
echo "<div class='stats-dashboard'>";
echo "<h3>今日访问: $today_visits</h3>";
echo "<h3>本周访问: $week_visits</h3>";
echo "<h4>热门页面:</h4>";
echo "<ul>";
foreach ($popular_pages as $page) {
echo "<li>{$page->page_url} ({$page->views} 次)</li>";
}
echo "</ul>";
echo "</div>";
}
3.2 实时访客显示工具
创建实时访客显示功能live-visitors.php:
<?php
/**
* 实时访客显示工具
*/
// 获取实时在线访客
function get_live_visitors() {
global $wpdb;
$table_name = $wpdb->prefix . 'website_stats';
// 获取最近5分钟内的活跃访客
$visitors = $wpdb->get_results(
$wpdb->prepare(
"SELECT DISTINCT ip_address, MAX(visited_at) as last_activity,
COUNT(*) as pageviews,
GROUP_CONCAT(DISTINCT page_url ORDER BY visited_at DESC SEPARATOR '|') as pages
FROM $table_name
WHERE visited_at >= DATE_SUB(%s, INTERVAL 5 MINUTE)
GROUP BY ip_address
ORDER BY last_activity DESC
LIMIT 20",
current_time('mysql')
)
);
return $visitors;
}
// 显示实时访客小工具
function display_live_visitors_widget() {
$visitors = get_live_visitors();
$count = count($visitors);
$output = "<div class='live-visitors-widget'>";
$output .= "<div class='live-header'>";
$output .= "<h3>👥 实时访客 ({$count})</h3>";
$output .= "<span class='live-indicator'></span>";
$output .= "</div>";
if ($count > 0) {
$output .= "<div class='visitors-list'>";
foreach ($visitors as $visitor) {
$pages = explode('|', $visitor->pages);
$last_page = $pages[0];
$time_ago = human_time_diff(strtotime($visitor->last_activity), current_time('timestamp'));
$output .= "<div class='visitor-item'>";
$output .= "<div class='visitor-ip'>{$visitor->ip_address}</div>";
$output .= "<div class='visitor-info'>";
$output .= "<span>浏览 {$visitor->pageviews} 页</span>";
$output .= "<span>最后活动: {$time_ago}前</span>";
$output .= "</div>";
$output .= "<div class='visitor-page'>正在浏览: " . esc_html($last_page) . "</div>";
$output .= "</div>";
}
$output .= "</div>";
} else {
$output .= "<p class='no-visitors'>暂无活跃访客</p>";
}
$output .= "</div>";
return $output;
}
add_shortcode('live_visitors', 'display_live_visitors_widget');
// 添加实时访客AJAX端点
add_action('wp_ajax_get_live_visitors_data', 'ajax_get_live_visitors');
add_action('wp_ajax_nopriv_get_live_visitors_data', 'ajax_get_live_visitors');
function ajax_get_live_visitors() {
$visitors = get_live_visitors();
$data = array();
foreach ($visitors as $visitor) {
$data[] = array(
'ip' => $visitor->ip_address,
'last_activity' => human_time_diff(strtotime($visitor->last_activity), current_time('timestamp')),
'pageviews' => $visitor->pageviews,
'current_page' => explode('|', $visitor->pages)[0]
);
}
wp_send_json_success(array(
'count' => count($visitors),
'visitors' => $data,
'timestamp' => current_time('mysql')
));
}
3.3 文件上传与分享工具
创建文件上传功能file-uploader.php:
<?php
/**
* 文件上传与分享工具
*/
// 添加上传短代码
function file_uploader_shortcode($atts) {
$atts = shortcode_atts(array(
'max_size' => '10', // MB
'allowed_types' => 'jpg,jpeg,png,pdf,doc,docx',
'title' => '文件上传'
), $atts);
$nonce = wp_create_nonce('file_upload_nonce');
$output = "<div class='file-uploader-widget'>";
$output .= "<h3>{$atts['title']}</h3>";
$output .= "<div class='upload-area' id='drop-area'>";
$output .= "<p>拖放文件到此处或点击选择</p>";
$output .= "<input type='file' id='file-input' multiple accept='." . str_replace(',', ',.', $atts['allowed_types']) . "'>";
$output .= "<button class='upload-btn'>选择文件</button>";
$output .= "</div>";
$output .= "<div class='file-list' id='file-list'></div>";
$output .= "<div class='upload-progress' style='display:none;'>";
$output .= "<div class='progress-bar'><div class='progress'></div></div>";
$output .= "<span class='progress-text'>0%</span>";
$output .= "</div>";
$output .= "<input type='hidden' id='upload_nonce' value='{$nonce}'>";
$output .= "<input type='hidden' id='max_size' value='{$atts['max_size']}'>";
$output .= "</div>";
return $output;
}
add_shortcode('file_uploader', 'file_uploader_shortcode');
// 处理文件上传
add_action('wp_ajax_handle_file_upload', 'handle_file_upload');
add_action('wp_ajax_nopriv_handle_file_upload', 'handle_file_upload');
function handle_file_upload() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'file_upload_nonce')) {
wp_send_json_error('安全验证失败');
}
// 检查文件
if (!isset($_FILES['file'])) {
wp_send_json_error('没有文件被上传');
}
$file = $_FILES['file'];
$max_size = intval($_POST['max_size']) * 1024 * 1024; // 转换为字节
// 检查文件大小
if ($file['size'] > $max_size) {
wp_send_json_error('文件大小超过限制');
}
// 检查文件类型
$allowed_types = explode(',', 'jpg,jpeg,png,pdf,doc,docx');
$file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($file_ext, $allowed_types)) {
wp_send_json_error('不支持的文件类型');
}
// 创建上传目录
$upload_dir = wp_upload_dir();
$custom_dir = $upload_dir['basedir'] . '/shared-files/' . date('Y/m');
if (!file_exists($custom_dir)) {
wp_mkdir_p($custom_dir);
}
// 生成唯一文件名
$unique_name = uniqid() . '_' . sanitize_file_name($file['name']);
$file_path = $custom_dir . '/' . $unique_name;
// 移动文件
if (move_uploaded_file($file['tmp_name'], $file_path)) {
// 保存文件信息到数据库
global $wpdb;
$table_name = $wpdb->prefix . 'shared_files';
$share_code = wp_generate_password(8, false);
$expiry_date = date('Y-m-d H:i:s', strtotime('+7 days'));
$wpdb->insert(
$table_name,
array(
'original_name' => $file['name'],
'file_path' => $file_path,
'file_size' => $file['size'],
'file_type' => $file_ext,
'share_code' => $share_code,
'uploaded_by' => get_current_user_id(),
'expiry_date' => $expiry_date,
'uploaded_at' => current_time('mysql')
)
);
