/** * Permissions & Security domain schemas. * Section keys must stay aligned with the router and PHP schema provider. */ export const permissionsSchemas = { /** * Login / captcha / access guard settings */ login: { key: 'permissions.login', title: '人机验证', icon: 'fa fas fa-shield-alt', description: '配置云验证码服务商,并选择需要强制人机验证的前端场景。', defaults: { enabled: false, active_provider: '', mode: 'always', enabled_scenarios: [ 'comment', 'login', 'register', 'bind', 'bind_phone', 'lostpassword', 'change_password', 'change_email', 'verify_email', 'download', 'signin', ], tencent: {}, aliyun: {}, cloudflare: {}, geetest: {}, }, groups: [ { key: 'basic', title: '基础设置', icon: 'fa fas fa-cog', fields: [ { key: 'enabled', label: '启用人机验证', type: 'switch', help: '总开关:关闭后所有场景均不验证' }, { key: 'active_provider', label: '当前服务商', type: 'radio', buttonStyle: false, options: [ { label: '关闭', value: '' }, { label: '腾讯云 Captcha', value: 'tencent' }, { label: '阿里云 CAPTCHA 2.0', value: 'aliyun' }, { label: 'Cloudflare Turnstile', value: 'cloudflare' }, { label: '极验 GeeTest', value: 'geetest' }, ], dependsOn: { key: 'enabled', value: true }, }, { key: 'mode', label: '触发模式', type: 'radio', buttonStyle: false, options: [ { label: '始终显示', value: 'always' }, ], dependsOn: { key: 'enabled', value: true }, }, { key: 'enabled_scenarios', label: '启用场景', type: 'checkbox', help: '勾选 = 该场景需要人机验证。取消勾选则该场景放行。', dependsOn: { key: 'enabled', value: true }, options: [ { label: '发表评论', value: 'comment' }, { label: '用户登录', value: 'login' }, { label: '用户注册', value: 'register' }, { label: '绑定第三方', value: 'bind' }, { label: '绑定手机', value: 'bind_phone' }, { label: '找回密码', value: 'lostpassword' }, { label: '修改密码', value: 'change_password' }, { label: '更改邮箱', value: 'change_email' }, { label: '邮箱验证', value: 'verify_email' }, { label: '资源下载', value: 'download' }, { label: '每日签到', value: 'signin' }, { label: '前台投稿', value: 'front_submit' }, ], }, ], }, { key: 'providers', title: '服务商配置', icon: 'fa fas fa-server', description: '按当前选择的服务商填写对应密钥。', fields: [ { key: 'provider_hint', label: '配置说明', type: 'notice', alertType: 'info', alertContent: '下方会渲染当前验证码服务商的专属配置面板。保存仍通过统一 schema contract 进行。', dependsOn: { key: 'enabled', value: true }, }, { key: 'tencent', label: '腾讯云配置', type: 'custom', dependsOn: { key: 'active_provider', value: 'tencent' } }, { key: 'aliyun', label: '阿里云配置', type: 'custom', dependsOn: { key: 'active_provider', value: 'aliyun' } }, { key: 'cloudflare', label: 'Cloudflare 配置', type: 'custom', dependsOn: { key: 'active_provider', value: 'cloudflare' } }, { key: 'geetest', label: '极验配置', type: 'custom', dependsOn: { key: 'active_provider', value: 'geetest' } }, ], }, ], }, /** * Capability matrix metadata contract. * The live page is still orchestration-heavy custom UI for now. */ capabilities: { key: 'permissions.capabilities', title: '基本权限', icon: 'fa fas fa-user', description: '统一管理用户、投稿和评论的角色权限。', defaults: {}, groups: [], }, /** * Moderation settings */ moderation: { key: 'permissions.moderation', title: '评论审核', icon: 'fa fas fa-gavel', description: '管理评论审核、反垃圾、限流与拦截配置。', defaults: { enabled: false, akismet_enabled: false, akismet_site_url: '', akismet_blog_lang: 'zh-CN', akismet_api_key: '', ai_enabled: false, ai_moderate_comments: true, ai_moderate_background: true, auto_approve_low_risk: false, auto_reject_high_risk: false, low_risk_max_score: 35, high_risk_min_score: 80, blocked_keywords: '', rate_limit_enabled: false, rate_limit_min_interval: 8, rate_limit_max_per_hour: 15, geoip_enabled: false, geoip_block_countries: [], }, groups: [ { key: 'basic', title: '审核总开关', icon: 'fa fas fa-power-off', fields: [ { key: 'enabled', label: '启用审核系统', type: 'switch', help: '关闭后评论将不经过主题审核链路。' }, ], }, { key: 'akismet', title: 'Akismet', icon: 'fa fas fa-filter', fields: [ { key: 'akismet_enabled', label: '启用 Akismet', type: 'switch', dependsOn: { key: 'enabled', value: true } }, { key: 'akismet_site_url', label: 'Site URL', type: 'input', placeholder: 'https://your-site.com', dependsOn: { key: 'akismet_enabled', value: true } }, { key: 'akismet_blog_lang', label: '博客语言', type: 'input', placeholder: 'zh-CN', dependsOn: { key: 'akismet_enabled', value: true } }, { key: 'akismet_api_key', label: 'API Key', type: 'input', inputType: 'password', placeholder: 'Akismet API Key', dependsOn: { key: 'akismet_enabled', value: true } }, ], }, { key: 'ai', title: 'AI 审核', icon: 'fa fab fa-android', fields: [ { key: 'ai_enabled', label: '启用 AI 审核', type: 'switch', dependsOn: { key: 'enabled', value: true } }, { key: 'ai_api_hint', label: '审核 API 配置', type: 'notice', alertType: 'info', alertContent: 'API 接入(百度/阿里云等)在「扩展 → API内容审核」中统一配置,此处仅控制审核范围和策略。', dependsOn: { key: 'ai_enabled', value: true } }, { key: 'ai_moderate_comments', label: '用户评论', type: 'switch', dependsOn: { key: 'ai_enabled', value: true } }, { key: 'ai_moderate_background', label: '用户资料背景', type: 'switch', dependsOn: { key: 'ai_enabled', value: true } }, { key: 'auto_approve_low_risk', label: '低风险自动通过', type: 'switch', dependsOn: { key: 'ai_enabled', value: true } }, { key: 'auto_reject_high_risk', label: '高风险自动拒绝', type: 'switch', dependsOn: { key: 'ai_enabled', value: true } }, { key: 'low_risk_max_score', label: '低风险上限', type: 'number', min: 0, max: 100, dependsOn: { key: 'ai_enabled', value: true } }, { key: 'high_risk_min_score', label: '高风险下限', type: 'number', min: 0, max: 100, dependsOn: { key: 'ai_enabled', value: true } }, ], }, { key: 'keywords', title: '关键词拦截', icon: 'fa fas fa-ban', fields: [ { key: 'blocked_keywords', label: '屏蔽关键词列表', type: 'textarea', rows: 4, placeholder: '每行一个关键词,也支持 /regex/i 格式。命中后会进入待审核并记录原因。', dependsOn: { key: 'enabled', value: true } }, ], }, { key: 'rate-limit', title: '频率限制', icon: 'fa fas fa-clock', fields: [ { key: 'rate_limit_enabled', label: '启用频率限制', type: 'switch', dependsOn: { key: 'enabled', value: true } }, { key: 'rate_limit_min_interval', label: '最小间隔(秒)', type: 'number', min: 1, max: 300, dependsOn: { key: 'rate_limit_enabled', value: true } }, { key: 'rate_limit_max_per_hour', label: '每小时上限', type: 'number', min: 1, max: 200, dependsOn: { key: 'rate_limit_enabled', value: true } }, ], }, { key: 'geoip', title: 'GeoIP 拦截', icon: 'fa fas fa-globe', fields: [ { key: 'geoip_enabled', label: '启用 GeoIP 拦截', type: 'switch', dependsOn: { key: 'enabled', value: true } }, { key: 'geoip_hint', label: 'IP 数据源', type: 'notice', alertType: 'info', alertContent: '复用「扩展 → IP归属地」中配置的数据源和 API Key。', dependsOn: { key: 'geoip_enabled', value: true } }, { key: 'geoip_block_countries', label: '屏蔽国家/地区', type: 'custom', dependsOn: { key: 'geoip_enabled', value: true } }, ], }, ], }, /** * Attachment permissions */ attachment: { key: 'permissions.attachment', title: '附件权限', icon: 'fa fas fa-paperclip', description: '控制文件上传和附件下载权限。', defaults: { avatar_max_size: 2, submit_image_max_size: 5, comment_image_max_size: 2, resource_max_size: 50, }, groups: [ { key: 'profile', title: '用户资料卡背景图', icon: 'fa fas fa-user-circle', fields: [ { key: 'avatar_max_size', label: '头像/用户资料卡背景图大小上限 (MB)', type: 'number', min: 1, max: 10 }, ], }, { key: 'content', title: '内容上传', icon: 'fa fas fa-image', fields: [ { key: 'submit_image_max_size', label: '投稿图片大小上限 (MB)', type: 'number', min: 1, max: 20 }, { key: 'comment_image_max_size', label: '评论图片大小上限 (MB)', type: 'number', min: 1, max: 10 }, ], }, { key: 'resource', title: '资源附件', icon: 'fa fas fa-file-archive', fields: [ { key: 'resource_max_size', label: '资源附件大小上限 (MB)', type: 'number', min: 1, max: 200 }, ], }, ], }, };