<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">智能自动回复 · 评论机器人</title>
<!-- 干净轻量的样式,模拟社交评论面板 -->
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: #f2f4f8;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 2rem 1rem;
}
.card {
background: white;
max-width: 680px;
width: 100%;
border-radius: 28px;
box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.2);
padding: 1.8rem 2rem 2.2rem;
transition: all 0.1s ease;
}
h1 {
font-size: 1.7rem;
font-weight: 600;
letter-spacing: -0.01em;
display: flex;
align-items: center;
gap: 0.4rem;
color: #1e293b;
margin-bottom: 0.3rem;
}
.subhead {
font-size: 0.95rem;
color: #64748b;
border-left: 4px solid #3b82f6;
padding-left: 0.8rem;
margin-bottom: 1.8rem;
margin-top: 0.2rem;
}
.comment-thread {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 2rem;
max-height: 380px;
overflow-y: auto;
padding-right: 4px;
}
.comment-item {
display: flex;
gap: 0.8rem;
background: #f8fafc;
padding: 0.9rem 1.2rem;
border-radius: 20px;
border: 1px solid #e9edf2;
transition: 0.1s;
}
.comment-item:hover {
border-color: #cbd5e1;
}
.avatar {
width: 40px;
height: 40px;
background: #d1d9e6;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
color: #1f2937;
flex-shrink: 0;
}
.comment-body {
flex: 1;
}
.comment-author {
font-weight: 600;
font-size: 0.9rem;
color: #0f172a;
display: inline-block;
margin-right: 0.5rem;
}
.comment-time {
font-size: 0.7rem;
color: #94a3b8;
}
.comment-text {
margin: 0.25rem 0 0.35rem;
font-size: 0.95rem;
line-height: 1.4;
word-break: break-word;
color: #1e293b;
}
.reply-badge {
background: #eef2ff;
color: #2563eb;
font-size: 0.7rem;
font-weight: 500;
padding: 0.2rem 0.8rem;
border-radius: 30px;
display: inline-block;
border: 1px solid #c7d2fe;
margin-top: 0.2rem;
}
.reply-badge::before {
content: "↩️ 回复: ";
opacity: 0.7;
}
.empty-feed {
padding: 2.5rem 1rem;
text-align: center;
color: #64748b;
background: #f1f5f9;
border-radius: 40px;
font-size: 0.95rem;
}
.control-panel {
background: #f1f5f9;
padding: 1.3rem 1.5rem;
border-radius: 24px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 1rem 0.8rem;
margin-bottom: 1.2rem;
}
.auto-toggle {
display: flex;
align-items: center;
gap: 0.6rem;
}
.auto-toggle label {
font-weight: 500;
color: #1e293b;
}
.switch {
position: relative;
display: inline-block;
width: 46px;
height: 26px;
background: #cbd5e1;
border-radius: 40px;
cursor: pointer;
transition: 0.15s;
}
.switch.active {
background: #2563eb;
}
.switch::after {
content: "";
position: absolute;
top: 3px;
left: 3px;
width: 20px;
height: 20px;
background: white;
border-radius: 40px;
transition: 0.15s;
box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}
.switch.active::after {
transform: translateX(20px);
}
.incoming-control {
display: flex;
align-items: center;
gap: 0.4rem 0.8rem;
flex-wrap: wrap;
}
.btn {
background: white;
border: 1px solid #d1d9e6;
padding: 0.5rem 1rem;
border-radius: 40px;
font-weight: 500;
font-size: 0.85rem;
color: #1e293b;
cursor: pointer;
transition: 0.1s;
display: inline-flex;
align-items: center;
gap: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.02);
}
.btn-primary {
background: #2563eb;
border: 1px solid #2563eb;
color: white;
}
.btn-primary:hover {
background: #1d4ed8;
}
.btn-outline {
background: transparent;
border: 1px dashed #94a3b8;
color: #334155;
}
.btn-outline:hover {
background: #eef2ff;
border-color: #3b82f6;
}
.btn:hover {
transform: scale(0.97);
}
.badge {
background: #e2e8f0;
padding: 0.2rem 0.8rem;
border-radius: 40px;
font-size: 0.75rem;
color: #1e293b;
}
.counter {
font-size: 0.8rem;
color: #475569;
}
.footer-note {
font-size: 0.8rem;
color: #94a3b8;
text-align: center;
margin-top: 1rem;
border-top: 1px solid #e9edf2;
padding-top: 0.8rem;
}
.footer-note code {
background: #e9edf2;
padding: 0.2rem 0.4rem;
border-radius: 12px;
}
/* 滚动条美化 */
.comment-thread::-webkit-scrollbar {
width: 4px;
}
.comment-thread::-webkit-scrollbar-track {
background: #eef2f6;
border-radius: 10px;
}
.comment-thread::-webkit-scrollbar-thumb {
background: #b9c7da;
border-radius: 10px;
}
</style>
</head>
<body>
<div class="card">
<h1>💬 评论小助手</h1>
<div class="subhead">自动回复机器人 · 可配置规则</div>
<!-- 评论流 -->
<div class="comment-thread" id="commentFeed">
<!-- 由 JavaScript 动态渲染 -->
<div class="empty-feed">暂无评论,点击下方「模拟新评论」</div>
</div>
<!-- 控制栏 -->
<div class="control-panel">
<div class="auto-toggle">
<label for="autoSwitchBtn">🤖 自动回复</label>
<span id="autoSwitchBtn" class="switch active" role="button" tabindex="0" aria-label="自动回复开关"></span>
<span class="badge" id="statusBadge">开启</span>
</div>
<div class="incoming-control">
<button class="btn btn-primary" id="simulateCommentBtn">➕ 模拟评论</button>
<button class="btn btn-outline" id="clearCommentsBtn">🧹 清空</button>
</div>
</div>
<!-- 回复计数 & 自定义回复 -->
<div style="display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 0.5rem;">
<div class="counter" id="replyCounter">🤖 已自动回复 <span id="replyCountSpan">0</span> 条</div>
<div style="display: flex; gap: 6px;">
<input type="text" id="customReplyInput" placeholder="自定义回复内容..."
style="border:1px solid #d1d9e6; border-radius:40px; padding:0.4rem 1rem; font-size:0.85rem; background:white; width:180px; outline:none;"/>
<button class="btn" id="applyCustomReplyBtn" style="background:#e9edf2;">应用</button>
</div>
</div>
<div class="footer-note">
⚡ 自动回复开启时,每条新评论都会触发机器人回复
<code>当前规则: 关键词/默认</code>
</div>
</div>
<script>
(function(){
// --- 数据 ---
// 评论池 (初始几条演示)
let comments = [
{ id: 'c1', author: '小明', text: '这个教程太棒了!', time: '2分钟前', replied: true },
{ id: 'c2', author: '阿花', text: '请问支持批量操作吗?', time: '8分钟前', replied: true },
{ id: 'c3', author: '代码君', text: '写得很好,已收藏', time: '15分钟前', replied: false },
];
let replyCount = comments.filter(c => c.replied).length;
let autoReplyEnabled = true; // 开关
// 自定义回复模板 (默认)
let customReplyTemplate = '感谢你的评论! 🙌';
// 模拟用户数据
const randomAuthors = ['Lily', 'Mike', 'Zoe', 'Alex', 'Joy', 'Sam', 'River', 'Taylor'];
const randomMessages = [
'有没有更详细的例子?',
'太棒了,解决了我的问题 👍',
'什么时候更新下一部分?',
'请问这个兼容IE吗 😂',
'收藏了,慢慢看',
'很清晰,谢谢博主',
'有没有考虑出视频版?',
'代码可以再优化一下',
'正好需要这个,感谢!',
'为什么我运行报错?',
];
// DOM 元素
const feedEl = document.getElementById('commentFeed');
const replyCountSpan = document.getElementById('replyCountSpan');
const autoSwitchBtn = document.getElementById('autoSwitchBtn');
const statusBadge = document.getElementById('statusBadge');
const simulateBtn = document.getElementById('simulateCommentBtn');
const clearBtn = document.getElementById('clearCommentsBtn');
const customReplyInput = document.getElementById('customReplyInput');
const applyCustomBtn = document.getElementById('applyCustomReplyBtn');
// ---- 辅助函数 ----
function generateId() {
return 'c_' + Date.now() + '_' + Math.random().toString(36).slice(2,6);
}
// 获取当前时间字符串 (相对)
function getFriendlyTime() {
return '刚刚';
}
// ---- 核心:自动回复逻辑 ----
function autoReplyForComment(commentText) {
if (!autoReplyEnabled) return null; // 开关关闭,不回复
// 基于关键词的智能回复 (可扩展)
const lower = commentText.toLowerCase();
if (lower.includes('谢谢') || lower.includes('感谢') || lower.includes('收藏') || lower.includes('很棒') || lower.includes('太好')) {
return '谢谢支持! 😊 有疑问随时留言。';
} else if (lower.includes('报错') || lower.includes('错误') || lower.includes('bug') || lower.includes('不行')) {
return '遇到问题请提供详细日志,我们会协助排查 🛠️';
} else if (lower.includes('视频') || lower.includes('教程') || lower.includes('更新')) {
return '内容持续制作中,关注不错过更新 🔔';
} else if (lower.includes('兼容') || lower.includes('ie') || lower.includes('浏览器')) {
return '目前兼容主流现代浏览器,IE建议升级 🧩';
} else {
// 默认回复: 使用自定义模板
return customReplyTemplate || '收到你的评论,谢谢! ✨';
}
}
// ---- 渲染评论列表 ----
function renderComments() {
if (comments.length === 0) {
feedEl.innerHTML = `<div class="empty-feed">📭 暂无评论,点击「模拟新评论」添加</div>`;
return;
}
let html = '';
comments.forEach(c => {
const avatarLetter = c.author.charAt(0).toUpperCase();
const replyBadge = c.replied
? `<div class="reply-badge">${c.repliedText || '机器人已回复'}</div>`
: '';
html += `
<div class="comment-item" data-comment-id="${c.id}">
<div class="avatar">${avatarLetter}</div>
<div class="comment-body">
<div>
<span class="comment-author">${c.author}</span>
<span class="comment-time">${c.time}</span>
</div>
<div class="comment-text">${c.text}</div>
${replyBadge}
</div>
</div>
`;
});
feedEl.innerHTML = html;
// 更新回复计数
replyCount = comments.filter(c => c.replied).length;
replyCountSpan.textContent = replyCount;
}
// ---- 添加新评论 (模拟) ----
function addComment(author, text, time, replied = false, repliedText = '') {
const newComment = {
id: generateId(),
author: author,
text: text,
time: time || getFriendlyTime(),
replied: replied,
repliedText: repliedText || '',
};
// 如果自动回复开启,且评论没有被标记为已回复 (新评论)
if (autoReplyEnabled && !replied) {
const replyContent = autoReplyForComment(text);
if (replyContent) {
newComment.replied = true;
newComment.repliedText = replyContent;
}
}
comments.push(newComment);
renderComments();
// 滚动到底部 (最新评论)
setTimeout(() => {
feedEl.scrollTop = feedEl.scrollHeight;
}, 30);
}
// ---- 模拟一条随机评论 ----
function simulateRandomComment() {
const author = randomAuthors[Math.floor(Math.random() * randomAuthors.length)];
const text = randomMessages[Math.floor(Math.random() * randomMessages.length)];
// 10%几率生成自定义文本,更真实
const useCustom = Math.random() < 0.2;
const finalText = useCustom ? `请问${customReplyTemplate.slice(0, 12)}可以吗?` : text;
addComment(author, finalText, getFriendlyTime(), false);
}
// ---- 清空所有评论 ----
function clearAllComments() {
if (comments.length === 0) return;
comments = [];
renderComments();
}
// ---- 切换自动回复 ----
function toggleAutoReply() {
autoReplyEnabled = !autoReplyEnabled;
// 更新 UI
autoSwitchBtn.classList.toggle('active', autoReplyEnabled);
statusBadge.textContent = autoReplyEnabled ? '开启' : '关闭';
// 对现有未回复评论 批量回复 (如果开启)
if (autoReplyEnabled) {
let changed = false;
comments.forEach(c => {
if (!c.replied) {
const reply = autoReplyForComment(c.text);
if (reply) {
c.replied = true;
c.repliedText = reply;
changed = true;
}
}
});
if (changed) {
renderComments();
}
}
}
// ---- 应用自定义回复 ----
function applyCustomReply() {
const raw = customReplyInput.value.trim();
if (raw === '') {
// 恢复默认
customReplyTemplate = '感谢你的评论! 🙌';
customReplyInput.placeholder = '已重置为默认';
customReplyInput.value = '';
} else {
customReplyTemplate = raw;
// 闪烁提示
customReplyInput.placeholder = '✅ 已应用';
setTimeout(() => {
customReplyInput.placeholder = '自定义回复内容...';
}, 1200);
}
// 如果自动回复开启,刷新所有未回复评论? (谨慎: 只对新评论有效)
// 但为了体验,提示用户
if (autoReplyEnabled) {
// 可选项:重跑一次自动回复
let updated = false;
comments.forEach(c => {
if (!c.replied) {
const reply = autoReplyForComment(c.text);
if (reply) {
c.replied = true;
c.repliedText = reply;
updated = true;
}
}
});
if (updated) {
renderComments();
}
}
}
// ---- 初始化 + 事件绑定 ----
function init() {
// 初始渲染
// 补全初始评论的repliedText
comments.forEach(c => {
if (c.replied && !c.repliedText) {
c.repliedText = autoReplyForComment(c.text) || '感谢评论!';
}
});
renderComments();
replyCountSpan.textContent = comments.filter(c => c.replied).length;
// 开关
autoSwitchBtn.addEventListener('click', toggleAutoReply);
// 模拟评论
simulateBtn.addEventListener('click', simulateRandomComment);
// 清空
clearBtn.addEventListener('click', clearAllComments);
// 应用自定义回复
applyCustomBtn.addEventListener('click', applyCustomReply);
customReplyInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
applyCustomReply();
}
});
// 额外: 预置自定义输入框占位
customReplyInput.placeholder = '自定义回复...';
}
init();
})();
</script>
</body>
</html>
自动回复机制与交互
您可以开启或关闭自动回复,并自定义回复内容,它的核心逻辑是模拟真实评论环境并智能响应。

- 智能回复规则:机器人会根据评论中的关键词(如“谢谢”、“报错”)自动匹配预设的回复模板,您也可以在下方的输入框中设置统一的默认回复内容。
- 模拟与测试:点击“模拟评论”按钮,系统会随机生成新评论,并触发自动回复,您可以通过“清空”按钮重置对话,方便测试不同规则。
- 状态监控:控制面板清晰显示自动回复的开启/关闭状态,并统计已自动回复的评论总数,让您对机器人的工作效果一目了然。