refactor: 移除 settings.php 中重复的 AI 垃圾评论识别部分
- 删除评论设置分类中的旧 AI 垃圾评论识别子分类(第 4619-5204 行) - 保留 AI 功能部分的评论审核设置(统一管理) - 减少 586 行重复代码 - 文件行数:7746 7160
This commit is contained in:
586
settings.php
586
settings.php
@@ -4616,592 +4616,6 @@ window.pjaxLoaded = function(){
|
||||
|
||||
</tr>
|
||||
|
||||
<tr><th class="subtitle"><h3 id="subsection-comment-spam-detection"><?php _e('AI 垃圾评论识别', 'argon');?></h3></th></tr>
|
||||
|
||||
<!-- 基础设置 -->
|
||||
<tr>
|
||||
<th><label><?php _e('启用 AI 识别', 'argon');?></label></th>
|
||||
<td>
|
||||
<?php $argon_comment_spam_detection_enable = get_option('argon_comment_spam_detection_enable', 'false'); ?>
|
||||
<label>
|
||||
<input type="checkbox" name="argon_comment_spam_detection_enable" value="true" <?php if ($argon_comment_spam_detection_enable=='true'){echo 'checked';}?>/>
|
||||
<?php _e('启用 AI 自动识别垃圾评论', 'argon');?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php _e('开启后,将使用 AI 自动识别广告、反动、违法等垃圾评论。', 'argon');?><br/>
|
||||
<?php _e('注意:需要先在 "文章功能 - AI 文章摘要" 中配置 AI 服务商和 API 密钥。', 'argon');?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 检测策略 -->
|
||||
<tr>
|
||||
<th><label><?php _e('检测策略', 'argon');?></label></th>
|
||||
<td>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: 600;">
|
||||
<?php _e('实时检测模式', 'argon');?>
|
||||
</label>
|
||||
<select name="argon_comment_spam_detection_mode" style="width: 100%; max-width: 400px;">
|
||||
<?php $argon_comment_spam_detection_mode = get_option('argon_comment_spam_detection_mode', 'manual'); ?>
|
||||
<option value="manual" <?php if ($argon_comment_spam_detection_mode=='manual'){echo 'selected';} ?>><?php _e('关闭实时检测', 'argon');?></option>
|
||||
<option value="keyword" <?php if ($argon_comment_spam_detection_mode=='keyword'){echo 'selected';} ?>><?php _e('关键字必查', 'argon');?></option>
|
||||
<option value="sample" <?php if ($argon_comment_spam_detection_mode=='sample'){echo 'selected';} ?>><?php _e('智能抽查(推荐)', 'argon');?></option>
|
||||
<option value="all" <?php if ($argon_comment_spam_detection_mode=='all'){echo 'selected';} ?>><?php _e('全量检测', 'argon');?></option>
|
||||
</select>
|
||||
<p class="description" style="margin-top: 8px;">
|
||||
<strong><?php _e('关闭实时检测', 'argon');?>:</strong><?php _e('只能使用手动批量扫描', 'argon');?><br/>
|
||||
<strong><?php _e('关键字必查', 'argon');?>:</strong><?php _e('只检测触发关键字的评论,精准防护,成本最低', 'argon');?><br/>
|
||||
<strong><?php _e('智能抽查', 'argon');?>:</strong><?php _e('根据用户信誉动态调整检测概率,平衡成本与效果', 'argon');?><br/>
|
||||
<strong><?php _e('全量检测', 'argon');?>:</strong><?php _e('每条新评论都检测,防护最严密但 API 消耗最高', 'argon');?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: 600;">
|
||||
<?php _e('智能抽查概率', 'argon');?>
|
||||
</label>
|
||||
<input type="number" name="argon_comment_spam_detection_sample_rate" min="1" max="100" value="<?php echo get_option('argon_comment_spam_detection_sample_rate', '20'); ?>" style="width: 80px;"/> %
|
||||
<p class="description" style="margin-top: 8px;">
|
||||
<?php _e('智能抽查模式的基础概率,默认 20%。系统会根据用户历史通过率自动调整:', 'argon');?><br/>
|
||||
<?php _e('• 信誉好的用户降低检测(最低 5%)', 'argon');?><br/>
|
||||
<?php _e('• 信誉差的用户提高检测(最高 80%)', 'argon');?><br/>
|
||||
<?php _e('• 关键字必查模式下此设置无效', 'argon');?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 关键字管理 -->
|
||||
<tr>
|
||||
<th><label><?php _e('关键字管理', 'argon');?></label></th>
|
||||
<td>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<?php $argon_comment_spam_detection_ai_learn = get_option('argon_comment_spam_detection_ai_learn', 'false'); ?>
|
||||
<label style="display: block; margin-bottom: 10px;">
|
||||
<input type="checkbox" name="argon_comment_spam_detection_ai_learn" value="true" <?php if ($argon_comment_spam_detection_ai_learn=='true'){echo 'checked';}?>/>
|
||||
<strong><?php _e('启用 AI 主动学习关键字', 'argon');?></strong>
|
||||
</label>
|
||||
<p class="description" style="margin: 0 0 15px 24px;">
|
||||
<?php _e('开启后,系统会分析管理员的审核决策,自动提取并优化关键字:', 'argon');?><br/>
|
||||
<?php _e('• 当 AI 判断与管理员决策不一致时,使用 AI 提取关键词', 'argon');?><br/>
|
||||
<?php _e('• 统计关键词在垃圾评论和正常评论中的出现频率', 'argon');?><br/>
|
||||
<?php _e('• 置信度 > 70% 且出现 >= 3 次的关键词自动加入下方列表', 'argon');?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: 600;">
|
||||
<?php _e('手动添加关键字', 'argon');?>
|
||||
</label>
|
||||
<textarea rows="8" cols="70" name="argon_comment_spam_detection_keywords" placeholder="<?php _e('每行一个关键字或短语', 'argon');?>" style="width: 100%; max-width: 800px;"><?php echo get_option('argon_comment_spam_detection_keywords', ''); ?></textarea>
|
||||
<p class="description">
|
||||
<?php _e('每行一个关键字或短语,支持中英文。当评论的用户名或内容包含这些关键字时:', 'argon');?><br/>
|
||||
<?php _e('• 关键字必查模式:立即进行 AI 检测', 'argon');?><br/>
|
||||
<?php _e('• 智能抽查/全量检测模式:提高检测优先级', 'argon');?><br/>
|
||||
<?php _e('常见示例:', 'argon');?> <code>加微信</code>, <code>联系QQ</code>, <code>点击链接</code>, <code>免费领取</code>, <code>刷单</code>, <code>兼职</code>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
$learned_keywords = get_option('argon_comment_spam_learned_keywords', []);
|
||||
if (!empty($learned_keywords) && is_array($learned_keywords)) {
|
||||
echo '<div style="margin-top: 20px; padding: 15px; background: #f7fafc; border-radius: 4px; border-left: 4px solid var(--themecolor, #5e72e4);">';
|
||||
echo '<h4 style="margin: 0 0 10px 0; color: #2d3748;">' . __('AI 学习到的关键字', 'argon') . '</h4>';
|
||||
echo '<div style="max-height: 200px; overflow-y: auto;">';
|
||||
echo '<table style="width: 100%; border-collapse: collapse; background: #fff; border-radius: 4px; overflow: hidden;">';
|
||||
echo '<thead><tr style="background: #edf2f7;">';
|
||||
echo '<th style="text-align: left; padding: 10px; font-weight: 600;">' . __('关键字', 'argon') . '</th>';
|
||||
echo '<th style="text-align: center; padding: 10px; font-weight: 600;">' . __('垃圾', 'argon') . '</th>';
|
||||
echo '<th style="text-align: center; padding: 10px; font-weight: 600;">' . __('正常', 'argon') . '</th>';
|
||||
echo '<th style="text-align: center; padding: 10px; font-weight: 600;">' . __('置信度', 'argon') . '</th>';
|
||||
echo '<th style="text-align: center; padding: 10px; font-weight: 600;">' . __('状态', 'argon') . '</th>';
|
||||
echo '</tr></thead><tbody>';
|
||||
|
||||
// 按置信度排序
|
||||
uasort($learned_keywords, function($a, $b) {
|
||||
return $b['confidence'] <=> $a['confidence'];
|
||||
});
|
||||
|
||||
$current_keywords_array = array_filter(array_map('trim', explode("\n", get_option('argon_comment_spam_detection_keywords', ''))));
|
||||
|
||||
foreach ($learned_keywords as $keyword => $stats) {
|
||||
$confidence = round($stats['confidence'] * 100);
|
||||
$color = $confidence >= 70 ? '#48bb78' : ($confidence >= 50 ? '#ed8936' : '#a0aec0');
|
||||
$is_added = in_array($keyword, $current_keywords_array);
|
||||
|
||||
echo '<tr style="border-bottom: 1px solid #e2e8f0;">';
|
||||
echo '<td style="padding: 10px;"><code style="background: #edf2f7; padding: 2px 6px; border-radius: 3px;">' . esc_html($keyword) . '</code></td>';
|
||||
echo '<td style="text-align: center; padding: 10px;">' . $stats['spam_count'] . '</td>';
|
||||
echo '<td style="text-align: center; padding: 10px;">' . $stats['normal_count'] . '</td>';
|
||||
echo '<td style="text-align: center; padding: 10px;"><span style="color: ' . $color . '; font-weight: 600;">' . $confidence . '%</span></td>';
|
||||
echo '<td style="text-align: center; padding: 10px;">';
|
||||
if ($is_added) {
|
||||
echo '<span style="color: #48bb78; font-weight: 600;">✓ ' . __('已添加', 'argon') . '</span>';
|
||||
} elseif ($confidence >= 70 && $stats['spam_count'] >= 3) {
|
||||
echo '<span style="color: #ed8936; font-weight: 600;">⚠ ' . __('待添加', 'argon') . '</span>';
|
||||
} else {
|
||||
echo '<span style="color: #a0aec0;">○ ' . __('观察中', 'argon') . '</span>';
|
||||
}
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
echo '</tbody></table></div>';
|
||||
echo '<p class="description" style="margin: 10px 0 0 0; font-size: 12px;">';
|
||||
echo __('• 绿色:置信度 ≥ 70%,已自动添加到关键字列表', 'argon') . '<br/>';
|
||||
echo __('• 橙色:置信度 50-70%,观察中', 'argon') . '<br/>';
|
||||
echo __('• 灰色:置信度 < 50%,数据不足', 'argon');
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- AI 配置 -->
|
||||
<tr>
|
||||
<th><label><?php _e('AI 配置', 'argon');?></label></th>
|
||||
<td>
|
||||
<select name="argon_comment_spam_detection_auto_action">
|
||||
<?php $argon_comment_spam_detection_auto_action = get_option('argon_comment_spam_detection_auto_action', 'trash'); ?>
|
||||
<option value="trash" <?php if ($argon_comment_spam_detection_auto_action=='trash'){echo 'selected';} ?>><?php _e('自动移入回收站', 'argon');?></option>
|
||||
<option value="hold" <?php if ($argon_comment_spam_detection_auto_action=='hold'){echo 'selected';} ?>><?php _e('标记为待审核', 'argon');?></option>
|
||||
<option value="mark" <?php if ($argon_comment_spam_detection_auto_action=='mark'){echo 'selected';} ?>><?php _e('仅标记不处理', 'argon');?></option>
|
||||
</select>
|
||||
<p class="description">
|
||||
<strong><?php _e('自动移入回收站', 'argon');?>:</strong><?php _e('检测到垃圾评论立即移入回收站(推荐)', 'argon');?><br/>
|
||||
<strong><?php _e('标记为待审核', 'argon');?>:</strong><?php _e('将垃圾评论状态改为待审核,需要管理员手动审核', 'argon');?><br/>
|
||||
<strong><?php _e('仅标记不处理', 'argon');?>:</strong><?php _e('只在评论元数据中标记,不改变评论状态', 'argon');?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('检测范围', 'argon');?></label></th>
|
||||
<td>
|
||||
<?php $argon_comment_spam_detection_exclude_logged_in = get_option('argon_comment_spam_detection_exclude_logged_in', 'true'); ?>
|
||||
<label style="display: block; margin-bottom: 8px;">
|
||||
<input type="checkbox" name="argon_comment_spam_detection_exclude_logged_in" value="true" <?php if ($argon_comment_spam_detection_exclude_logged_in=='true'){echo 'checked';}?>/>
|
||||
<?php _e('跳过已登录用户的评论', 'argon');?>
|
||||
</label>
|
||||
<p class="description"><?php _e('开启后,已登录用户(包括管理员、编辑等)的评论不会被检测。', 'argon');?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('白名单', 'argon');?></label></th>
|
||||
<td>
|
||||
<textarea rows="4" cols="70" name="argon_comment_spam_detection_whitelist" placeholder="<?php _e('每行一个邮箱或 IP 地址', 'argon');?>"><?php echo get_option('argon_comment_spam_detection_whitelist', ''); ?></textarea>
|
||||
<p class="description">
|
||||
<?php _e('白名单中的邮箱或 IP 地址的评论不会被检测,每行一个。', 'argon');?><br/>
|
||||
<?php _e('示例:user@example.com 或 192.168.1.1', 'argon');?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('Prompt 模式', 'argon');?></label></th>
|
||||
<td>
|
||||
<select name="argon_comment_spam_detection_prompt_mode" id="argon-prompt-mode-select">
|
||||
<?php $prompt_mode = get_option('argon_comment_spam_detection_prompt_mode', 'standard'); ?>
|
||||
<option value="minimal" <?php if ($prompt_mode=='minimal'){echo 'selected';} ?>><?php _e('极简模式', 'argon');?></option>
|
||||
<option value="standard" <?php if ($prompt_mode=='standard'){echo 'selected';} ?>><?php _e('标准模式(推荐)', 'argon');?></option>
|
||||
<option value="enhanced" <?php if ($prompt_mode=='enhanced'){echo 'selected';} ?>><?php _e('增强模式', 'argon');?></option>
|
||||
<option value="custom" <?php if ($prompt_mode=='custom'){echo 'selected';} ?>><?php _e('自定义 Prompt', 'argon');?></option>
|
||||
</select>
|
||||
<p class="description">
|
||||
<strong><?php _e('极简模式', 'argon');?></strong>: <?php _e('省 token,快速检测,理由简短(约 100-150 tokens)', 'argon');?><br/>
|
||||
<strong><?php _e('标准模式', 'argon');?></strong>: <?php _e('平衡准确性和成本,包含置信度和处理建议(约 200-300 tokens)', 'argon');?><br/>
|
||||
<strong><?php _e('增强模式', 'argon');?></strong>: <?php _e('多维度分析,更准确,包含综合分析(约 300-500 tokens)', 'argon');?><br/>
|
||||
<strong><?php _e('自定义 Prompt', 'argon');?></strong>: <?php _e('使用下方自定义的 Prompt', 'argon');?>
|
||||
</p>
|
||||
|
||||
<div id="argon-custom-prompt-container" style="margin-top: 15px; <?php echo ($prompt_mode !== 'custom') ? 'display: none;' : ''; ?>">
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: 600;">
|
||||
<?php _e('自定义检测提示词', 'argon');?>
|
||||
</label>
|
||||
<select id="argon-spam-prompt-template" style="margin-bottom: 10px; width: 100%; max-width: 400px;">
|
||||
<option value=""><?php _e('选择预设模板...', 'argon');?></option>
|
||||
<option value="default"><?php _e('默认模板(平衡)', 'argon');?></option>
|
||||
<option value="strict"><?php _e('严格模式', 'argon');?></option>
|
||||
<option value="loose"><?php _e('宽松模式', 'argon');?></option>
|
||||
<option value="minimal"><?php _e('极简模式(省 token)', 'argon');?></option>
|
||||
</select>
|
||||
<textarea rows="6" cols="70" id="argon-spam-prompt-textarea" name="argon_comment_spam_detection_prompt" style="width: 100%; max-width: 800px;"><?php echo get_option('argon_comment_spam_detection_prompt', '你是一个专业的内容审核助手。请判断以下评论是否为垃圾评论。垃圾评论包括但不限于:广告推广、反动言论、错误政治观点、时政敏感内容、违法信息、色情暴力、恶意攻击等。
|
||||
|
||||
请仅返回 JSON 格式:{"is_spam": true/false, "reason": "理由(25字以内)"}
|
||||
|
||||
如果是正常评论,reason 填写 "正常"。如果是垃圾评论,简要说明原因。'); ?></textarea>
|
||||
<p class="description"><?php _e('自定义 AI 识别垃圾评论时使用的提示词。建议保持简洁以降低 token 消耗。', 'argon');?></p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// Prompt 模式切换
|
||||
$('#argon-prompt-mode-select').on('change', function() {
|
||||
const mode = $(this).val();
|
||||
if (mode === 'custom') {
|
||||
$('#argon-custom-prompt-container').slideDown(200);
|
||||
} else {
|
||||
$('#argon-custom-prompt-container').slideUp(200);
|
||||
}
|
||||
});
|
||||
|
||||
// 预设模板
|
||||
const templates = {
|
||||
'default': '你是一个专业的内容审核助手。请判断以下评论是否为垃圾评论。垃圾评论包括但不限于:广告推广、反动言论、错误政治观点、时政敏感内容、违法信息、色情暴力、恶意攻击等。\n\n请仅返回 JSON 格式:{"is_spam": true/false, "reason": "理由(25字以内)"}\n\n如果是正常评论,reason 填写 "正常"。如果是垃圾评论,简要说明原因。',
|
||||
'strict': '你是严格的内容审核助手。判断评论是否为垃圾评论,包括:广告、推广、营销、反动、政治敏感、违法、色情、暴力、恶意攻击、无意义灌水、重复内容等。\n\n返回 JSON:{"is_spam": true/false, "reason": "理由(25字内)"}\n\n有任何可疑迹象都标记为垃圾。',
|
||||
'loose': '判断评论是否为明显的垃圾评论:广告推广、违法内容、色情暴力。\n\n返回 JSON:{"is_spam": true/false, "reason": "理由(25字内)"}\n\n只标记明显的垃圾评论,对正常讨论保持宽容。',
|
||||
'minimal': '判断是否垃圾评论(广告/违法/色情/暴力)。返回:{"is_spam": true/false, "reason": "理由(20字内)"}'
|
||||
};
|
||||
|
||||
$('#argon-spam-prompt-template').on('change', function() {
|
||||
const template = $(this).val();
|
||||
if (template && templates[template]) {
|
||||
$('#argon-spam-prompt-textarea').val(templates[template]);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('自动处理阈值', 'argon');?></label></th>
|
||||
<td>
|
||||
<label style="display: block; margin-bottom: 8px;">
|
||||
<?php _e('置信度阈值', 'argon');?>:
|
||||
<input type="number" name="argon_comment_spam_detection_confidence_threshold" min="50" max="100" step="5" value="<?php echo get_option('argon_comment_spam_detection_confidence_threshold', '85'); ?>" style="width: 80px;"/> %
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php _e('只有 AI 判断的置信度高于此阈值时,才会自动处理垃圾评论。', 'argon');?><br/>
|
||||
<?php _e('建议值:小型博客 90%,中型博客 85%,大型博客 80%', 'argon');?><br/>
|
||||
<?php _e('置信度低于阈值的评论会被标记为待审核,由管理员人工判断', 'argon');?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('隐私保护级别', 'argon');?></label></th>
|
||||
<td>
|
||||
<select name="argon_comment_spam_detection_privacy_level">
|
||||
<?php $privacy_level = get_option('argon_comment_spam_detection_privacy_level', 'standard'); ?>
|
||||
<option value="standard" <?php if ($privacy_level=='standard'){echo 'selected';} ?>><?php _e('标准模式', 'argon');?></option>
|
||||
<option value="strict" <?php if ($privacy_level=='strict'){echo 'selected';} ?>><?php _e('严格模式', 'argon');?></option>
|
||||
</select>
|
||||
<p class="description">
|
||||
<strong><?php _e('标准模式', 'argon');?></strong>: <?php _e('发送邮箱域名和 IP 地址段(如 @example.com、192.168.*.*)', 'argon');?><br/>
|
||||
<strong><?php _e('严格模式', 'argon');?></strong>: <?php _e('不发送任何用户标识信息,仅发送评论内容和文章信息', 'argon');?><br/>
|
||||
<?php _e('严格模式下检测准确率可能降低,但更好地保护用户隐私', 'argon');?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('推荐配置', 'argon');?></label></th>
|
||||
<td>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<button type="button" class="button" id="argon-apply-config-small"><?php _e('小型博客配置', 'argon');?></button>
|
||||
<button type="button" class="button" id="argon-apply-config-medium" style="margin-left: 10px;"><?php _e('中型博客配置', 'argon');?></button>
|
||||
<button type="button" class="button" id="argon-apply-config-large" style="margin-left: 10px;"><?php _e('大型博客配置', 'argon');?></button>
|
||||
</div>
|
||||
<p class="description">
|
||||
<strong><?php _e('小型博客', 'argon');?></strong> (<?php _e('评论量 < 100/天', 'argon');?>): <?php _e('标准模式,阈值 90%,抽查 20%', 'argon');?><br/>
|
||||
<strong><?php _e('中型博客', 'argon');?></strong> (<?php _e('评论量 100-500/天', 'argon');?>): <?php _e('标准模式,阈值 85%,抽查 30%', 'argon');?><br/>
|
||||
<strong><?php _e('大型博客', 'argon');?></strong> (<?php _e('评论量 > 500/天', 'argon');?>): <?php _e('极简模式,阈值 80%,抽查 40%', 'argon');?>
|
||||
</p>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('#argon-apply-config-small').on('click', function() {
|
||||
if (confirm('<?php _e('确定要应用小型博客推荐配置吗?', 'argon');?>')) {
|
||||
$('select[name="argon_comment_spam_detection_prompt_mode"]').val('standard');
|
||||
$('input[name="argon_comment_spam_detection_confidence_threshold"]').val('90');
|
||||
$('input[name="argon_comment_spam_detection_sample_rate"]').val('20');
|
||||
alert('<?php _e('已应用小型博客配置,请保存设置', 'argon');?>');
|
||||
}
|
||||
});
|
||||
|
||||
$('#argon-apply-config-medium').on('click', function() {
|
||||
if (confirm('<?php _e('确定要应用中型博客推荐配置吗?', 'argon');?>')) {
|
||||
$('select[name="argon_comment_spam_detection_prompt_mode"]').val('standard');
|
||||
$('input[name="argon_comment_spam_detection_confidence_threshold"]').val('85');
|
||||
$('input[name="argon_comment_spam_detection_sample_rate"]').val('30');
|
||||
alert('<?php _e('已应用中型博客配置,请保存设置', 'argon');?>');
|
||||
}
|
||||
});
|
||||
|
||||
$('#argon-apply-config-large').on('click', function() {
|
||||
if (confirm('<?php _e('确定要应用大型博客推荐配置吗?', 'argon');?>')) {
|
||||
$('select[name="argon_comment_spam_detection_prompt_mode"]').val('minimal');
|
||||
$('input[name="argon_comment_spam_detection_confidence_threshold"]').val('80');
|
||||
$('input[name="argon_comment_spam_detection_sample_rate"]').val('40');
|
||||
alert('<?php _e('已应用大型博客配置,请保存设置', 'argon');?>');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('手动批量检测', 'argon');?></label></th>
|
||||
<td>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<button type="button" class="button button-primary" id="argon-spam-detection-scan-all"><?php _e('全站评论扫描', 'argon');?></button>
|
||||
<button type="button" class="button" id="argon-spam-detection-scan-pending" style="margin-left: 10px;"><?php _e('仅扫描待审核评论', 'argon');?></button>
|
||||
<span id="argon-spam-detection-status" style="margin-left: 15px; color: #666;"></span>
|
||||
</div>
|
||||
<div id="argon-spam-detection-progress" style="display: none; margin-bottom: 15px;">
|
||||
<div style="background: #f0f0f1; border-radius: 4px; height: 24px; position: relative; overflow: hidden;">
|
||||
<div id="argon-spam-detection-progress-bar" style="background: var(--themecolor, #5e72e4); height: 100%; width: 0%; transition: width 0.3s;"></div>
|
||||
<span id="argon-spam-detection-progress-text" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 12px; font-weight: 600; color: #333;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="argon-spam-detection-results" style="display: none; margin-top: 15px; padding: 15px; background: #fff; border: 1px solid #ddd; border-radius: 4px; max-height: 400px; overflow-y: auto;">
|
||||
<div id="argon-spam-detection-results-content"></div>
|
||||
</div>
|
||||
<p class="description">
|
||||
<?php _e('手动扫描现有评论,识别垃圾评论。扫描不包括已在回收站的评论。', 'argon');?><br/>
|
||||
<?php _e('检测到的垃圾评论会被标记,您可以选择性地移入回收站。', 'argon');?>
|
||||
</p>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
let isScanning = false;
|
||||
|
||||
function startScan(scanType) {
|
||||
if (isScanning) {
|
||||
alert('<?php _e('正在扫描中,请稍候', 'argon');?>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('<?php _e('确定要开始扫描吗?这将一次性检测所有评论,可能需要较长时间。', 'argon');?>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
isScanning = true;
|
||||
$('#argon-spam-detection-scan-all, #argon-spam-detection-scan-pending').prop('disabled', true);
|
||||
$('#argon-spam-detection-status').text('<?php _e('正在扫描...请耐心等待', 'argon');?>');
|
||||
$('#argon-spam-detection-progress').show();
|
||||
$('#argon-spam-detection-results').hide();
|
||||
$('#argon-spam-detection-progress-bar').css('width', '50%');
|
||||
$('#argon-spam-detection-progress-text').text('<?php _e('处理中...', 'argon');?>');
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'argon_spam_detection_scan',
|
||||
nonce: '<?php echo wp_create_nonce('argon_spam_detection_scan'); ?>',
|
||||
scan_type: scanType
|
||||
}, function(response) {
|
||||
isScanning = false;
|
||||
$('#argon-spam-detection-scan-all, #argon-spam-detection-scan-pending').prop('disabled', false);
|
||||
$('#argon-spam-detection-progress-bar').css('width', '100%');
|
||||
$('#argon-spam-detection-progress-text').text('100%');
|
||||
|
||||
if (response.success) {
|
||||
const data = response.data;
|
||||
$('#argon-spam-detection-status').text('<?php _e('扫描完成', 'argon');?> - <?php _e('共检测', 'argon');?> ' + data.total + ' <?php _e('条评论', 'argon');?>');
|
||||
displayResults(data.results);
|
||||
} else {
|
||||
$('#argon-spam-detection-status').text('<?php _e('扫描失败', 'argon');?>: ' + (response.data || ''));
|
||||
$('#argon-spam-detection-progress').hide();
|
||||
}
|
||||
}).fail(function(xhr, status, error) {
|
||||
isScanning = false;
|
||||
$('#argon-spam-detection-scan-all, #argon-spam-detection-scan-pending').prop('disabled', false);
|
||||
$('#argon-spam-detection-status').text('<?php _e('请求失败', 'argon');?>: ' + error);
|
||||
$('#argon-spam-detection-progress').hide();
|
||||
});
|
||||
}
|
||||
|
||||
function displayResults(results) {
|
||||
if (!results || results.length === 0) {
|
||||
$('#argon-spam-detection-results-content').html('<p style="color: #46b450; font-weight: 600;"><span class="dashicons dashicons-yes-alt" style="font-size: 20px; vertical-align: middle;"></span> <?php _e('未发现垃圾评论,所有评论都是正常的!', 'argon');?></p>');
|
||||
$('#argon-spam-detection-results').show();
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<p style="color: #dc3232; font-weight: 600; margin-bottom: 15px;"><span class="dashicons dashicons-warning" style="font-size: 20px; vertical-align: middle;"></span> <?php _e('发现', 'argon');?> ' + results.length + ' <?php _e('条疑似垃圾评论', 'argon');?></p>';
|
||||
html += '<table class="wp-list-table widefat fixed striped" style="margin-top: 10px;"><thead><tr><th style="width: 80px;"><?php _e('评论 ID', 'argon');?></th><th style="width: 120px;"><?php _e('作者', 'argon');?></th><th><?php _e('内容', 'argon');?></th><th style="width: 150px;"><?php _e('识别理由', 'argon');?></th><th style="width: 100px;"><?php _e('操作', 'argon');?></th></tr></thead><tbody>';
|
||||
|
||||
results.forEach(function(item) {
|
||||
html += '<tr data-comment-id="' + item.comment_id + '">';
|
||||
html += '<td>' + item.comment_id + '</td>';
|
||||
html += '<td>' + $('<div>').text(item.author).html() + '</td>';
|
||||
html += '<td style="max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="' + $('<div>').text(item.content).html() + '">' + $('<div>').text(item.content).html() + '</td>';
|
||||
html += '<td>' + $('<div>').text(item.reason).html() + '</td>';
|
||||
html += '<td><button type="button" class="button button-small argon-spam-trash-btn" data-comment-id="' + item.comment_id + '"><?php _e('移入回收站', 'argon');?></button></td>';
|
||||
html += '</tr>';
|
||||
});
|
||||
|
||||
html += '</tbody></table>';
|
||||
$('#argon-spam-detection-results-content').html(html);
|
||||
$('#argon-spam-detection-results').show();
|
||||
}
|
||||
|
||||
$(document).on('click', '.argon-spam-trash-btn', function() {
|
||||
const btn = $(this);
|
||||
const commentId = btn.data('comment-id');
|
||||
|
||||
if (!confirm('<?php _e('确定要将此评论移入回收站吗?', 'argon');?>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
btn.prop('disabled', true).text('<?php _e('处理中...', 'argon');?>');
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'argon_spam_detection_trash_comment',
|
||||
nonce: '<?php echo wp_create_nonce('argon_spam_detection_trash_comment'); ?>',
|
||||
comment_id: commentId
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
btn.closest('tr').fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
if ($('#argon-spam-detection-results-content tbody tr').length === 0) {
|
||||
$('#argon-spam-detection-results-content').html('<p style="color: #46b450; font-weight: 600;"><span class="dashicons dashicons-yes-alt" style="font-size: 20px; vertical-align: middle;"></span> <?php _e('所有标记的垃圾评论已处理', 'argon');?></p>');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('<?php _e('操作失败', 'argon');?>: ' + (response.data || ''));
|
||||
btn.prop('disabled', false).text('<?php _e('移入回收站', 'argon');?>');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#argon-spam-detection-scan-all').on('click', function() {
|
||||
startScan('all');
|
||||
});
|
||||
|
||||
$('#argon-spam-detection-scan-pending').on('click', function() {
|
||||
startScan('pending');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('检测统计', 'argon');?></label></th>
|
||||
<td>
|
||||
<?php
|
||||
// 获取统计数据
|
||||
$learning_module = new Argon_Spam_Learning_Module();
|
||||
$stats = $learning_module->get_statistics();
|
||||
$error_handler = new Argon_Spam_API_Error_Handler();
|
||||
$api_status = $error_handler->get_status();
|
||||
?>
|
||||
<div style="background: #f9f9f9; padding: 15px; border-radius: 4px; margin-bottom: 15px;">
|
||||
<p style="margin: 0 0 10px 0; font-weight: 600;"><?php _e('检测准确率', 'argon');?></p>
|
||||
<p style="margin: 0 0 5px 0;">
|
||||
<?php _e('最近 7 天', 'argon');?>:
|
||||
<strong style="color: <?php echo $stats['accuracy_7d'] >= 80 ? '#46b450' : '#dc3232'; ?>;">
|
||||
<?php echo number_format($stats['accuracy_7d'], 2); ?>%
|
||||
</strong>
|
||||
(<?php echo $stats['error_rate_7d']['total']; ?> <?php _e('次检测', 'argon');?>)
|
||||
</p>
|
||||
<p style="margin: 0;">
|
||||
<?php _e('最近 30 天', 'argon');?>:
|
||||
<strong style="color: <?php echo $stats['accuracy_30d'] >= 80 ? '#46b450' : '#dc3232'; ?>;">
|
||||
<?php echo number_format($stats['accuracy_30d'], 2); ?>%
|
||||
</strong>
|
||||
(<?php echo $stats['error_rate_30d']['total']; ?> <?php _e('次检测', 'argon');?>)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php if ($api_status['is_disabled']): ?>
|
||||
<div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 12px; margin-bottom: 15px;">
|
||||
<p style="margin: 0; color: #856404;">
|
||||
<strong><?php _e('⚠️ 实时检测已自动禁用', 'argon');?></strong><br/>
|
||||
<?php _e('原因:连续 API 调用失败', 'argon');?><br/>
|
||||
<?php _e('剩余时间', 'argon');?>: <?php echo $api_status['remaining_minutes']; ?> <?php _e('分钟', 'argon');?>
|
||||
</p>
|
||||
<button type="button" class="button" id="argon-manual-enable-detection" style="margin-top: 10px;">
|
||||
<?php _e('立即恢复检测', 'argon');?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="description">
|
||||
<?php _e('显示 AI 检测的准确率统计。准确率 = (总检测数 - 误判数) / 总检测数', 'argon');?><br/>
|
||||
<?php _e('误判包括:AI 认为是垃圾但管理员批准的(假阳性),以及 AI 认为正常但管理员标记为垃圾的(假阴性)', 'argon');?>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('#argon-manual-enable-detection').on('click', function() {
|
||||
if (!confirm('<?php _e('确定要立即恢复实时检测吗?', 'argon');?>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'argon_manual_enable_spam_detection',
|
||||
nonce: '<?php echo wp_create_nonce('argon_manual_enable'); ?>'
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
alert('<?php _e('已恢复实时检测', 'argon');?>');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('<?php _e('操作失败', 'argon');?>: ' + (response.data || ''));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><label><?php _e('API 错误日志', 'argon');?></label></th>
|
||||
<td>
|
||||
<?php
|
||||
$errors = $error_handler->get_errors(10);
|
||||
if (empty($errors)): ?>
|
||||
<p style="color: #46b450;">✓ <?php _e('暂无 API 错误', 'argon');?></p>
|
||||
<?php else: ?>
|
||||
<div style="max-height: 300px; overflow-y: auto; background: #f9f9f9; padding: 10px; border-radius: 4px;">
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div style="padding: 8px; margin-bottom: 8px; background: #fff; border-left: 3px solid #dc3232; border-radius: 2px;">
|
||||
<p style="margin: 0 0 5px 0; font-size: 13px;">
|
||||
<strong><?php echo esc_html($error['type']); ?></strong>
|
||||
<span style="float: right; color: #666; font-size: 12px;">
|
||||
<?php echo date('Y-m-d H:i:s', $error['timestamp']); ?>
|
||||
</span>
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 12px; color: #666;">
|
||||
<?php echo esc_html($error['message']); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<button type="button" class="button" id="argon-clear-error-log" style="margin-top: 10px;">
|
||||
<?php _e('清除错误日志', 'argon');?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="description">
|
||||
<?php _e('显示最近 10 条 API 错误日志。连续失败 3 次后会自动禁用实时检测 1 小时', 'argon');?>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('#argon-clear-error-log').on('click', function() {
|
||||
if (!confirm('<?php _e('确定要清除所有错误日志吗?', 'argon');?>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'argon_clear_spam_error_log',
|
||||
nonce: '<?php echo wp_create_nonce('argon_clear_errors'); ?>'
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
alert('<?php _e('已清除错误日志', 'argon');?>');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('<?php _e('操作失败', 'argon');?>: ' + (response.data || ''));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><th class="subtitle"><h3 id="subsection-comment-appearance"><?php _e('评论区外观', 'argon');?></h3></th></tr>
|
||||
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user