feat: 完成设置页完整重组

- 将评论功能、AI垃圾评论识别、评论区外观从验证码与安全移到评论设置
- 将'验证码与安全'拆分为'验证码设置'(第17分类)和'反馈与安全'(第18分类)
- 验证码设置包含:验证码配置、场景验证码
- 反馈与安全包含:反馈设置、速率限制
- 高级设置调整为第19个分类
- 评论设置现在包含:评论分页、发送评论、评论功能、AI垃圾评论识别、评论区外观
This commit is contained in:
2026-01-22 14:45:59 +08:00
parent 0fb1d11cad
commit b471bbc7b8
2 changed files with 548 additions and 471 deletions

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
将评论相关设置从验证码与安全移到评论设置分类
"""
def find_line_with_text(lines, text):
"""查找包含指定文本的行号"""
for i, line in enumerate(lines):
if text in line:
return i
return -1
def reorganize():
with open('settings.php', 'r', encoding='utf-8') as f:
lines = f.readlines()
print(f"原始文件: {len(lines)}")
# 1. 找到关键位置
comment_section_start = find_line_with_text(lines, '<!-- ========== 16. 评论设置 ==========')
comment_submit_end = -1
# 找到"发送评论"子分类的结束位置
for i in range(comment_section_start, len(lines)):
if '<!-- ========== 16. 验证码与安全 ==========' in lines[i]:
comment_submit_end = i
break
# 找到"返回评论系统"的位置(评论功能开始)
comment_features_start = find_line_with_text(lines, '<!-- ========== 返回评论系统 ==========')
# 找到文件结束位置(保存按钮之前)
file_end = find_line_with_text(lines, '<input type="submit"')
print(f"评论设置开始: {comment_section_start + 1}")
print(f"发送评论结束: {comment_submit_end + 1}")
print(f"评论功能开始: {comment_features_start + 1}")
print(f"文件结束: {file_end + 1}")
# 2. 提取评论功能、AI垃圾评论识别、评论区外观部分
comment_features_content = lines[comment_features_start:file_end]
# 3. 删除"返回评论系统"注释,改为正常的子分类标题
new_comment_features = []
for line in comment_features_content:
if '<!-- ========== 返回评论系统 ==========' in line:
continue # 跳过这个注释
new_comment_features.append(line)
# 4. 重新组织文件
new_lines = []
# 添加评论设置之前的所有内容
new_lines.extend(lines[:comment_submit_end])
# 添加评论功能、AI垃圾评论识别、评论区外观
new_lines.extend(new_comment_features)
# 添加验证码与安全及之后的内容
new_lines.extend(lines[comment_submit_end:comment_features_start])
# 添加文件结束部分
new_lines.extend(lines[file_end:])
print(f"重组后: {len(new_lines)}")
# 写入文件
with open('settings.php', 'w', encoding='utf-8') as f:
f.writelines(new_lines)
print("✓ 完成将评论功能、AI垃圾评论识别、评论区外观移到评论设置分类")
if __name__ == '__main__':
reorganize()

View File

@@ -3089,7 +3089,7 @@ function themeoptions_page(){
</tr>
<!-- ========== 15. 高级设置 ========== -->
<!-- ========== 19. 高级设置 ========== -->
<tr><th class="subtitle"><h2 id="section-advanced"><?php _e('高级设置', 'argon');?></h2></th></tr>
<tr><th class="subtitle"><h3 id="subsection-scripts"><?php _e('自定义脚本', 'argon');?></h3></th></tr>
@@ -3279,476 +3279,6 @@ window.pjaxLoaded = function(){
</tr>
<!-- ========== 16. 验证码与安全 ========== -->
<tr><th class="subtitle"><h2 id="section-security"><?php _e('验证码与安全', 'argon');?></h2></th></tr>
<tr><th class="subtitle"><h3 id="subsection-captcha"><?php _e('验证码设置', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('全局验证码开关', 'argon');?></label></th>
<td>
<select name="argon_need_captcha">
<?php $argon_need_captcha = get_option('argon_need_captcha', get_option('argon_comment_need_captcha', 'true')); ?>
<option value="true" <?php if ($argon_need_captcha=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($argon_need_captcha=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('全局验证码开关,当各场景设置为"使用全局设置"时生效', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('验证码类型', 'argon');?></label></th>
<td>
<select name="argon_captcha_type">
<?php $argon_captcha_type = get_option('argon_captcha_type', 'math'); ?>
<option value="math" <?php if ($argon_captcha_type=='math'){echo 'selected';} ?>><?php _e('数学运算', 'argon');?></option>
<option value="geetest" <?php if ($argon_captcha_type=='geetest'){echo 'selected';} ?>><?php _e('极验验证码', 'argon');?></option>
</select>
<p class="description"><?php _e('选择验证码类型。极验验证码需要配置相关参数。', 'argon');?></p>
</td>
</tr>
<tr id="geetest_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验验证码 ID', 'argon');?></label></th>
<td>
<input type="text" name="argon_geetest_captcha_id" value="<?php echo esc_attr(get_option('argon_geetest_captcha_id', '')); ?>" class="regular-text" required />
<p class="description"><?php _e('在极验后台获取的验证码 ID必填项', 'argon');?></p>
</td>
</tr>
<tr id="geetest_key_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验验证码 Key', 'argon');?></label></th>
<td>
<input type="text" name="argon_geetest_captcha_key" value="<?php echo esc_attr(get_option('argon_geetest_captcha_key', '')); ?>" class="regular-text" required />
<p class="description"><?php _e('在极验后台获取的验证码私钥,必填项', 'argon');?></p>
</td>
</tr>
<tr id="geetest_server_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验 API 服务器', 'argon');?></label></th>
<td>
<input type="url" name="argon_geetest_api_server" value="<?php echo esc_attr(get_option('argon_geetest_api_server', 'https://gcaptcha4.geetest.com')); ?>" class="regular-text" />
<p class="description"><?php _e('极验 API 服务器地址默认为官方服务器。请确保URL格式正确', 'argon');?></p>
</td>
</tr>
<script>
jQuery(document).ready(function($) {
// 验证Geetest配置
function validateGeetestConfig() {
var captchaType = $('select[name="argon_captcha_type"]').val();
if (captchaType === 'geetest') {
var captchaId = $('input[name="argon_geetest_captcha_id"]').val().trim();
var captchaKey = $('input[name="argon_geetest_captcha_key"]').val().trim();
var apiServer = $('input[name="argon_geetest_api_server"]').val().trim();
if (!captchaId || !captchaKey) {
alert('<?php _e('使用极验验证码时,验证码 ID 和 Key 为必填项', 'argon'); ?>');
return false;
}
// 验证API服务器URL格式
if (apiServer && !apiServer.match(/^https?:\/\/.+/)) {
alert('<?php _e('API 服务器地址格式不正确请输入完整的URL', 'argon'); ?>');
return false;
}
}
return true;
}
$('select[name="argon_captcha_type"]').change(function() {
if ($(this).val() === 'geetest') {
$('#geetest_settings, #geetest_key_settings, #geetest_server_settings').show();
} else {
$('#geetest_settings, #geetest_key_settings, #geetest_server_settings').hide();
}
});
// 表单提交时验证
$('form').submit(function(e) {
if (!validateGeetestConfig()) {
e.preventDefault();
return false;
}
});
});
</script>
<tr>
<th><label><?php _e('使用 Ajax 获取验证码', 'argon');?></label></th>
<td>
<select name="argon_get_captcha_by_ajax">
<?php $argon_get_captcha_by_ajax = get_option('argon_get_captcha_by_ajax'); ?>
<option value="false" <?php if ($argon_get_captcha_by_ajax=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
<option value="true" <?php if ($argon_get_captcha_by_ajax=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
</select>
<p class="description"><?php _e('如果使用了 CDN 缓存,验证码不会刷新,请开启此选项,否则请不要开启。', 'argon');?></p>
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-captcha-scenes"><?php _e('场景验证码', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('评论验证码', 'argon');?></label></th>
<td>
<select name="argon_comment_captcha_mode">
<?php $argon_comment_captcha_mode = get_option('argon_comment_captcha_mode', 'global'); ?>
<option value="global" <?php if ($argon_comment_captcha_mode=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($argon_comment_captcha_mode=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($argon_comment_captcha_mode=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('评论是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('TODO 催促验证码', 'argon');?></label></th>
<td>
<select name="argon_todo_captcha_mode">
<?php $argon_todo_captcha_mode = get_option('argon_todo_captcha_mode', 'global'); ?>
<option value="global" <?php if ($argon_todo_captcha_mode=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($argon_todo_captcha_mode=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($argon_todo_captcha_mode=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('访客催促 TODO 时是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('友链申请验证码', 'argon');?></label></th>
<td>
<select name="argon_friend_link_captcha">
<?php $flink_captcha = get_option('argon_friend_link_captcha', 'global'); ?>
<option value="global" <?php if ($flink_captcha=='global' || $flink_captcha=='same'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($flink_captcha=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($flink_captcha=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('友链申请表单是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈提交验证码', 'argon');?></label></th>
<td>
<select name="argon_feedback_captcha_mode">
<?php $feedback_captcha = get_option('argon_feedback_captcha_mode', 'global'); ?>
<option value="global" <?php if ($feedback_captcha=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($feedback_captcha=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($feedback_captcha=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('问题反馈页面提交时是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-feedback"><?php _e('反馈设置', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('新反馈通知管理员', 'argon');?></label></th>
<td>
<select name="argon_feedback_notify_admin">
<?php $feedback_notify_admin = get_option('argon_feedback_notify_admin', 'true'); ?>
<option value="true" <?php if ($feedback_notify_admin=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($feedback_notify_admin=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('收到新反馈时是否发送邮件通知管理员', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈回复/完结通知用户', 'argon');?></label></th>
<td>
<select name="argon_feedback_notify_user">
<?php $feedback_notify_user = get_option('argon_feedback_notify_user', 'true'); ?>
<option value="true" <?php if ($feedback_notify_user=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($feedback_notify_user=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('反馈收到回复或被标记为已解决时,是否发送邮件通知用户。邮件中包含授权链接,用户可通过链接查看反馈详情(无论反馈是否公开)', 'argon');?></p>
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-rate-limit"><?php _e('速率限制', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('全局 IP 黑名单', 'argon');?></label></th>
<td>
<textarea name="argon_global_blocked_ips" rows="8" cols="70" placeholder="<?php _e('每行一个 IP 地址', 'argon');?>"><?php echo get_option('argon_global_blocked_ips', ''); ?></textarea>
<p class="description">
<?php _e('被屏蔽的 IP 地址将无法提交评论、反馈、友链申请等操作。支持以下格式:', 'argon');?><br>
• <?php _e('精确匹配192.168.1.100', 'argon');?><br>
• <?php _e('通配符192.168.1.*', 'argon');?><br>
• <?php _e('CIDR 格式192.168.1.0/24', 'argon');?>
</p>
</td>
</tr>
<tr>
<th><label><?php _e('友链申请频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_flink_apply_limit" min="1" max="50" value="<?php echo get_option('argon_flink_apply_limit', '3'); ?>" style="width:80px;"/> <?php _e('次', 'argon');?> /
<input type="number" name="argon_flink_apply_period" min="60" max="86400" value="<?php echo get_option('argon_flink_apply_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内提交友链申请的次数。默认1小时内最多3次', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈提交频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_feedback_submit_limit" min="1" max="100" value="<?php echo get_option('argon_feedback_submit_limit', '5'); ?>" style="width:80px;"/> <?php _e('次', 'argon');?> /
<input type="number" name="argon_feedback_submit_period" min="60" max="86400" value="<?php echo get_option('argon_feedback_submit_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内提交反馈的次数防止恶意刷屏。默认1小时内最多5次', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈图片上传频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_feedback_upload_limit" min="1" max="100" value="<?php echo get_option('argon_feedback_upload_limit', '20'); ?>" style="width:80px;"/> <?php _e('张', 'argon');?> /
<input type="number" name="argon_feedback_upload_period" min="60" max="86400" value="<?php echo get_option('argon_feedback_upload_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内上传图片的数量。默认1小时内最多20张', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('评论速率限制', 'argon');?></label></th>
<td>
<select name="argon_rate_limit_enable">
<?php $argon_rate_limit_enable = get_option('argon_rate_limit_enable', 'true'); ?>
<option value="false" <?php if ($argon_rate_limit_enable=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
<option value="true" <?php if ($argon_rate_limit_enable=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
</select>
<p class="description"><?php _e('按 IP 进行速率限制,防止短时间内频繁评论。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('速率窗口(秒)', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_window" value="<?php echo esc_attr(get_option('argon_rate_limit_window', 300)); ?>" class="regular-text" min="30" step="1" />
<p class="description"><?php _e('统计窗口长度,建议不小于 30 秒。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('窗口内最大次数', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_max_count" value="<?php echo esc_attr(get_option('argon_rate_limit_max_count', 5)); ?>" class="regular-text" min="1" step="1" />
<p class="description"><?php _e('在一个统计窗口内允许的最大评论次数。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('两次最小间隔(秒)', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_min_interval" value="<?php echo esc_attr(get_option('argon_rate_limit_min_interval', 10)); ?>" class="regular-text" min="0" step="1" />
<p class="description"><?php _e('两次评论之间的最短时间间隔。', 'argon');?></p>
</td>
</tr>
<!-- ========== 返回评论系统 ========== -->
<tr><th class="subtitle"><h3 id="subsection-comment-features"><?php _e('评论功能', 'argon');?></h3></th></tr>
<tr>
@@ -5629,6 +5159,478 @@ window.pjaxLoaded = function(){
<p class="submit">
<!-- ========== 17. 验证码设置 ========== -->
<tr><th class="subtitle"><h2 id="section-captcha"><?php _e('验证码设置', 'argon');?></h2></th></tr>
<tr><th class="subtitle"><h3 id="subsection-captcha"><?php _e('验证码配置', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('全局验证码开关', 'argon');?></label></th>
<td>
<select name="argon_need_captcha">
<?php $argon_need_captcha = get_option('argon_need_captcha', get_option('argon_comment_need_captcha', 'true')); ?>
<option value="true" <?php if ($argon_need_captcha=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($argon_need_captcha=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('全局验证码开关,当各场景设置为"使用全局设置"时生效', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('验证码类型', 'argon');?></label></th>
<td>
<select name="argon_captcha_type">
<?php $argon_captcha_type = get_option('argon_captcha_type', 'math'); ?>
<option value="math" <?php if ($argon_captcha_type=='math'){echo 'selected';} ?>><?php _e('数学运算', 'argon');?></option>
<option value="geetest" <?php if ($argon_captcha_type=='geetest'){echo 'selected';} ?>><?php _e('极验验证码', 'argon');?></option>
</select>
<p class="description"><?php _e('选择验证码类型。极验验证码需要配置相关参数。', 'argon');?></p>
</td>
</tr>
<tr id="geetest_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验验证码 ID', 'argon');?></label></th>
<td>
<input type="text" name="argon_geetest_captcha_id" value="<?php echo esc_attr(get_option('argon_geetest_captcha_id', '')); ?>" class="regular-text" required />
<p class="description"><?php _e('在极验后台获取的验证码 ID必填项', 'argon');?></p>
</td>
</tr>
<tr id="geetest_key_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验验证码 Key', 'argon');?></label></th>
<td>
<input type="text" name="argon_geetest_captcha_key" value="<?php echo esc_attr(get_option('argon_geetest_captcha_key', '')); ?>" class="regular-text" required />
<p class="description"><?php _e('在极验后台获取的验证码私钥,必填项', 'argon');?></p>
</td>
</tr>
<tr id="geetest_server_settings" style="<?php echo ($argon_captcha_type != 'geetest') ? 'display:none;' : ''; ?>">
<th><label><?php _e('极验 API 服务器', 'argon');?></label></th>
<td>
<input type="url" name="argon_geetest_api_server" value="<?php echo esc_attr(get_option('argon_geetest_api_server', 'https://gcaptcha4.geetest.com')); ?>" class="regular-text" />
<p class="description"><?php _e('极验 API 服务器地址默认为官方服务器。请确保URL格式正确', 'argon');?></p>
</td>
</tr>
<script>
jQuery(document).ready(function($) {
// 验证Geetest配置
function validateGeetestConfig() {
var captchaType = $('select[name="argon_captcha_type"]').val();
if (captchaType === 'geetest') {
var captchaId = $('input[name="argon_geetest_captcha_id"]').val().trim();
var captchaKey = $('input[name="argon_geetest_captcha_key"]').val().trim();
var apiServer = $('input[name="argon_geetest_api_server"]').val().trim();
if (!captchaId || !captchaKey) {
alert('<?php _e('使用极验验证码时,验证码 ID 和 Key 为必填项', 'argon'); ?>');
return false;
}
// 验证API服务器URL格式
if (apiServer && !apiServer.match(/^https?:\/\/.+/)) {
alert('<?php _e('API 服务器地址格式不正确请输入完整的URL', 'argon'); ?>');
return false;
}
}
return true;
}
$('select[name="argon_captcha_type"]').change(function() {
if ($(this).val() === 'geetest') {
$('#geetest_settings, #geetest_key_settings, #geetest_server_settings').show();
} else {
$('#geetest_settings, #geetest_key_settings, #geetest_server_settings').hide();
}
});
// 表单提交时验证
$('form').submit(function(e) {
if (!validateGeetestConfig()) {
e.preventDefault();
return false;
}
});
});
</script>
<tr>
<th><label><?php _e('使用 Ajax 获取验证码', 'argon');?></label></th>
<td>
<select name="argon_get_captcha_by_ajax">
<?php $argon_get_captcha_by_ajax = get_option('argon_get_captcha_by_ajax'); ?>
<option value="false" <?php if ($argon_get_captcha_by_ajax=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
<option value="true" <?php if ($argon_get_captcha_by_ajax=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
</select>
<p class="description"><?php _e('如果使用了 CDN 缓存,验证码不会刷新,请开启此选项,否则请不要开启。', 'argon');?></p>
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-captcha-scenes"><?php _e('场景验证码', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('评论验证码', 'argon');?></label></th>
<td>
<select name="argon_comment_captcha_mode">
<?php $argon_comment_captcha_mode = get_option('argon_comment_captcha_mode', 'global'); ?>
<option value="global" <?php if ($argon_comment_captcha_mode=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($argon_comment_captcha_mode=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($argon_comment_captcha_mode=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('评论是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('TODO 催促验证码', 'argon');?></label></th>
<td>
<select name="argon_todo_captcha_mode">
<?php $argon_todo_captcha_mode = get_option('argon_todo_captcha_mode', 'global'); ?>
<option value="global" <?php if ($argon_todo_captcha_mode=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($argon_todo_captcha_mode=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($argon_todo_captcha_mode=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('访客催促 TODO 时是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('友链申请验证码', 'argon');?></label></th>
<td>
<select name="argon_friend_link_captcha">
<?php $flink_captcha = get_option('argon_friend_link_captcha', 'global'); ?>
<option value="global" <?php if ($flink_captcha=='global' || $flink_captcha=='same'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($flink_captcha=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($flink_captcha=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('友链申请表单是否需要验证码', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈提交验证码', 'argon');?></label></th>
<td>
<select name="argon_feedback_captcha_mode">
<?php $feedback_captcha = get_option('argon_feedback_captcha_mode', 'global'); ?>
<option value="global" <?php if ($feedback_captcha=='global'){echo 'selected';} ?>><?php _e('使用全局设置', 'argon');?></option>
<option value="enabled" <?php if ($feedback_captcha=='enabled'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="disabled" <?php if ($feedback_captcha=='disabled'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('问题反馈页面提交时是否需要验证码', 'argon');?></p>
</td>
</tr>
<!-- ========== 18. 反馈与安全 ========== -->
<tr><th class="subtitle"><h2 id="section-feedback-security"><?php _e('反馈与安全', 'argon');?></h2></th></tr>
<tr><th class="subtitle"><h3 id="subsection-feedback"><?php _e('反馈设置', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('新反馈通知管理员', 'argon');?></label></th>
<td>
<select name="argon_feedback_notify_admin">
<?php $feedback_notify_admin = get_option('argon_feedback_notify_admin', 'true'); ?>
<option value="true" <?php if ($feedback_notify_admin=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($feedback_notify_admin=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('收到新反馈时是否发送邮件通知管理员', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈回复/完结通知用户', 'argon');?></label></th>
<td>
<select name="argon_feedback_notify_user">
<?php $feedback_notify_user = get_option('argon_feedback_notify_user', 'true'); ?>
<option value="true" <?php if ($feedback_notify_user=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
<option value="false" <?php if ($feedback_notify_user=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
</select>
<p class="description"><?php _e('反馈收到回复或被标记为已解决时,是否发送邮件通知用户。邮件中包含授权链接,用户可通过链接查看反馈详情(无论反馈是否公开)', 'argon');?></p>
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-rate-limit"><?php _e('速率限制', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('全局 IP 黑名单', 'argon');?></label></th>
<td>
<textarea name="argon_global_blocked_ips" rows="8" cols="70" placeholder="<?php _e('每行一个 IP 地址', 'argon');?>"><?php echo get_option('argon_global_blocked_ips', ''); ?></textarea>
<p class="description">
<?php _e('被屏蔽的 IP 地址将无法提交评论、反馈、友链申请等操作。支持以下格式:', 'argon');?><br>
• <?php _e('精确匹配192.168.1.100', 'argon');?><br>
• <?php _e('通配符192.168.1.*', 'argon');?><br>
• <?php _e('CIDR 格式192.168.1.0/24', 'argon');?>
</p>
</td>
</tr>
<tr>
<th><label><?php _e('友链申请频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_flink_apply_limit" min="1" max="50" value="<?php echo get_option('argon_flink_apply_limit', '3'); ?>" style="width:80px;"/> <?php _e('次', 'argon');?> /
<input type="number" name="argon_flink_apply_period" min="60" max="86400" value="<?php echo get_option('argon_flink_apply_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内提交友链申请的次数。默认1小时内最多3次', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈提交频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_feedback_submit_limit" min="1" max="100" value="<?php echo get_option('argon_feedback_submit_limit', '5'); ?>" style="width:80px;"/> <?php _e('次', 'argon');?> /
<input type="number" name="argon_feedback_submit_period" min="60" max="86400" value="<?php echo get_option('argon_feedback_submit_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内提交反馈的次数防止恶意刷屏。默认1小时内最多5次', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('反馈图片上传频率限制', 'argon');?></label></th>
<td>
<input type="number" name="argon_feedback_upload_limit" min="1" max="100" value="<?php echo get_option('argon_feedback_upload_limit', '20'); ?>" style="width:80px;"/> <?php _e('张', 'argon');?> /
<input type="number" name="argon_feedback_upload_period" min="60" max="86400" value="<?php echo get_option('argon_feedback_upload_period', '3600'); ?>" style="width:100px;"/> <?php _e('秒', 'argon');?>
<p class="description"><?php _e('限制单个用户在指定时间内上传图片的数量。默认1小时内最多20张', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('评论速率限制', 'argon');?></label></th>
<td>
<select name="argon_rate_limit_enable">
<?php $argon_rate_limit_enable = get_option('argon_rate_limit_enable', 'true'); ?>
<option value="false" <?php if ($argon_rate_limit_enable=='false'){echo 'selected';} ?>><?php _e('禁用', 'argon');?></option>
<option value="true" <?php if ($argon_rate_limit_enable=='true'){echo 'selected';} ?>><?php _e('启用', 'argon');?></option>
</select>
<p class="description"><?php _e('按 IP 进行速率限制,防止短时间内频繁评论。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('速率窗口(秒)', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_window" value="<?php echo esc_attr(get_option('argon_rate_limit_window', 300)); ?>" class="regular-text" min="30" step="1" />
<p class="description"><?php _e('统计窗口长度,建议不小于 30 秒。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('窗口内最大次数', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_max_count" value="<?php echo esc_attr(get_option('argon_rate_limit_max_count', 5)); ?>" class="regular-text" min="1" step="1" />
<p class="description"><?php _e('在一个统计窗口内允许的最大评论次数。', 'argon');?></p>
</td>
</tr>
<tr>
<th><label><?php _e('两次最小间隔(秒)', 'argon');?></label></th>
<td>
<input type="number" name="argon_rate_limit_min_interval" value="<?php echo esc_attr(get_option('argon_rate_limit_min_interval', 10)); ?>" class="regular-text" min="0" step="1" />
<p class="description"><?php _e('两次评论之间的最短时间间隔。', 'argon');?></p>
</td>
</tr>
<input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e('保存更改', 'argon');?>">
<a class="button button-secondary" style="margin-left: 8px;" onclick="importSettings()"><?php _e('导入设置', 'argon');?></a>