外观
本节说明CMS评论的数据结构、主题接口、主题内调用方式及管理后台,仅适用于CMS模式。
评论支持文章下的二级嵌套回复,类似B站回复用户名功能,登录用户评论默认通过审核,游客评论进入待审核状态。
评论表 {prefix}comments 包含字段:id、post_id、parent_id、uid、type、name、email、url、ip、user_agent、content、status、created_at。
{prefix}comments
id
post_id
parent_id
uid
type
name
email
url
ip
user_agent
content
status
created_at
评论状态包括待审核、已通过、垃圾和已删除。支持二级嵌套回复,parent_id 指向顶级评论,回复时接口返回 reply_to_name 用于前端展示回复用户名。
reply_to_name
统一入口:/anon/cms/comments,无需登录。
/anon/cms/comments
GET /anon/cms/comments?post_id={文章ID}
data.comments
data.currentUser
displayName
avatar
树形结构说明:data.comments 为根评论数组,每条根评论带有 children 数组(其回复列表),便于前端直接渲染层级。
children
单条评论结构(供主题/Vue 使用):
主题接口不返回 email,避免泄露。
POST /anon/cms/comments
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
approved
pending
重要:为防止广告机和恶意刷评论,系统为游客评论提供了验证码保护机制。
启用验证码:
在 server/app/useApp.php 中配置:
server/app/useApp.php
'captcha' => [ 'enabled' => true, // 启用验证码 ],
验证码行为:
GET /anon/auth/captcha
前端集成示例:
// 获取验证码 async function loadCaptcha() { const response = await fetch('/anon/auth/captcha'); const data = await response.json(); if (data.success) { // data.data.image 为 Base64 图片 // data.data.code 为验证码字符串(仅用于调试,生产环境不应返回) return data.data.image; } } // 提交评论时包含验证码 const formData = new FormData(); formData.append('post_id', postId); formData.append('content', content); formData.append('name', name); formData.append('email', email); formData.append('captcha', captchaCode); // 验证码字段 const response = await fetch('/anon/cms/comments', { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } });
错误响应:
comment=captcha_required
comment=captcha_error
"请输入验证码"
"验证码错误,请重新输入"
安全特性:
在主题模板/组件中可直接使用以下方法(由 Anon_Cms_Theme_View 提供):
Anon_Cms_Theme_View
$this->getCommentsByPostId($postId)
$this->getPostComments($postId)
$this->getCommentDisplayName()
$this->isLoggedIn()
默认主题评论区组件(app/components/comments.php)用法示例:
app/components/comments.php
$post = $post ?? $this->post(); if (!$post || $post->type() !== 'post' || $post->get('comment_status', 'open') !== 'open') { return; } $postId = (int) $post->id(); $commentLoggedIn = $this->isLoggedIn(); $commentDisplayName = $this->getCommentDisplayName() ?: '登录用户';
评论列表通常由前端通过 GET /anon/cms/comments?post_id=... 拉取并渲染;若需服务端直接输出列表,可 $this->getCommentsByPostId($postId) 得到相同树形结构。
/anon/cms/comments?post_id=...
window.__anonInitComments()
initPage()
app.avatar
getAvatarByEmail
app.captcha.enabled
spam
trash
comment_status
open
closed
$post->get('comment_status', 'open')
注意:评论功能与访问日志(AccessLog)是独立的系统:
AccessLog
posts.views
access_log_enabled
comments
如需查看访问日志相关配置,请参考 管理后台 - 访问日志。
评论功能
本节说明CMS评论的数据结构、主题接口、主题内调用方式及管理后台,仅适用于CMS模式。
评论支持文章下的二级嵌套回复,类似B站回复用户名功能,登录用户评论默认通过审核,游客评论进入待审核状态。
评论表与状态
评论表
{prefix}comments包含字段:id、post_id、parent_id、uid、type、name、email、url、ip、user_agent、content、status、created_at。评论状态包括待审核、已通过、垃圾和已删除。支持二级嵌套回复,
parent_id指向顶级评论,回复时接口返回reply_to_name用于前端展示回复用户名。主题评论接口(前端/主题调用)
统一入口:
/anon/cms/comments,无需登录。GET:获取评论列表
GET /anon/cms/comments?post_id={文章ID}data.comments为树形结构的已通过评论;已登录时附带data.currentUser(displayName、name、avatar,不含 email)。树形结构说明:
data.comments为根评论数组,每条根评论带有children数组(其回复列表),便于前端直接渲染层级。单条评论结构(供主题/Vue 使用):
主题接口不返回 email,避免泄露。
POST:提交评论
POST /anon/cms/comments,Content-Type: application/x-www-form-urlencoded,建议带X-Requested-With: XMLHttpRequest以收到 JSON 响应。post_id、content必填;未登录时需name、email,可选url;回复时传parent_id(父评论 ID,仅支持回复顶级评论)。post_id、content(及可选url、parent_id),name/email 由后端从当前用户补齐;登录用户评论默认approved,游客默认pending。验证码保护(防刷机制)
重要:为防止广告机和恶意刷评论,系统为游客评论提供了验证码保护机制。
启用验证码:
在
server/app/useApp.php中配置:验证码行为:
GET /anon/auth/captcha获取验证码图片(Base64 格式)前端集成示例:
错误响应:
comment=captcha_required:未提供验证码comment=captcha_error:验证码错误"请输入验证码"或"验证码错误,请重新输入"安全特性:
主题内 $this 调用
在主题模板/组件中可直接使用以下方法(由
Anon_Cms_Theme_View提供):$this->getCommentsByPostId($postId)$this->getPostComments($postId)$this->getCommentDisplayName()$this->isLoggedIn()默认主题评论区组件(
app/components/comments.php)用法示例:评论列表通常由前端通过 GET
/anon/cms/comments?post_id=...拉取并渲染;若需服务端直接输出列表,可$this->getCommentsByPostId($postId)得到相同树形结构。评论区脚本与 PJAX
window.__anonInitComments()(若存在)。默认主题在initPage()中已调用,进入文章页后评论列表会正常加载。管理后台评论管理
头像与 Gravatar
avatar,为空时由用户表逻辑按 email 生成 Gravatar(配置app.avatar,默认 cravatar.cn)。avatar时按评论中的 email 调用用户库的getAvatarByEmail生成 Gravatar,与用户表策略一致。安全防护措施
1. 验证码保护
app.captcha.enabled控制2. 评论审核机制
approved(已通过),立即显示pending(待审核),需管理员审核后显示3. IP 和 User-Agent 记录
4. 评论状态管理
pending:待审核(游客评论默认状态)approved:已通过(登录用户默认状态,或管理员审核后)spam:垃圾评论(管理员标记)trash:已删除(软删除,可恢复)5. 文章评论开关
comment_status字段)open时允许评论,其他值(如closed)时禁止评论$post->get('comment_status', 'open')检查评论状态访问日志与评论统计
注意:评论功能与访问日志(
AccessLog)是独立的系统:posts.views)独立于访问日志,不受access_log_enabled开关影响access_log_enabled开关仅控制访问日志记录,不影响评论功能comments表,与访问日志无关如需查看访问日志相关配置,请参考 管理后台 - 访问日志。