feat: SSR 帖/评举报与 Admin 处理

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-29 17:47:09 +08:00
parent 802f86605c
commit 83994e2707
16 changed files with 465 additions and 13 deletions

View File

@@ -11,8 +11,12 @@
<li><strong>{{.BoardCount}}</strong><span>板块</span></li>
<li><strong>{{.PendingPosts}}</strong><span>待审帖</span></li>
<li><strong>{{.PendingComments}}</strong><span>待审评</span></li>
<li><strong>{{.PendingReports}}</strong><span>待处理举报</span></li>
</ul>
<p class="j13-muted">有待审内容时请前往 <a href="/admin/moderation">内容审核</a>。</p>
<p class="j13-muted">
有待审内容时请前往 <a href="/admin/moderation">内容审核</a>
有举报时请前往 <a href="/admin/reports">举报处理</a>。
</p>
</main>
{{template "base/footer" .}}
{{end}}

View File

@@ -3,6 +3,7 @@
<a href="/admin/dashboard"{{if eq .NavActive "dashboard"}} class="is-active"{{end}}>仪表盘</a>
<a href="/admin/boards"{{if eq .NavActive "boards"}} class="is-active"{{end}}>板块</a>
<a href="/admin/moderation"{{if eq .NavActive "moderation"}} class="is-active"{{end}}>审核</a>
<a href="/admin/reports"{{if eq .NavActive "reports"}} class="is-active"{{end}}>举报</a>
<a href="/admin/friend-links"{{if eq .NavActive "friend-links"}} class="is-active"{{end}}>友链</a>
<a href="/admin/pages"{{if eq .NavActive "pages"}} class="is-active"{{end}}>单页</a>
<a href="/admin/settings"{{if eq .NavActive "settings"}} class="is-active"{{end}}>设置</a>

View File

@@ -0,0 +1,55 @@
{{define "admin/reports"}}
{{template "base/head" .}}
{{template "base/navbar" .}}
<main class="j13-main j13-admin">
<h1>举报处理{{if gt .PendingCount 0}}(待处理 {{.PendingCount}}{{end}}</h1>
{{template "admin/nav" .}}
{{template "base/alert" .}}
<p class="j13-admin-filters">
<a href="/admin/reports?status=pending"{{if eq .StatusFilter "pending"}} class="is-active"{{end}}>待处理</a>
<a href="/admin/reports?status=resolved"{{if eq .StatusFilter "resolved"}} class="is-active"{{end}}>已处理</a>
<a href="/admin/reports?status=dismissed"{{if eq .StatusFilter "dismissed"}} class="is-active"{{end}}>已驳回</a>
<a href="/admin/reports?status=all"{{if eq .StatusFilter "all"}} class="is-active"{{end}}>全部</a>
</p>
{{if .Reports}}
<ul class="j13-admin-list">
{{range .Reports}}
<li class="j13-admin-card">
<p><strong>{{.TargetLabel}}</strong> · {{.ReasonLabel}} · {{.StatusLabel}}</p>
<p class="j13-muted">{{.CreatedAt}} · 举报人 {{if .ReporterName}}{{.ReporterName}}{{else}}—{{end}}
· <a href="/post/{{.PostID}}">查看帖子</a></p>
{{if .Detail}}<p>说明:{{.Detail}}</p>{{end}}
{{if .Pending}}
<form method="post" action="/admin/reports/{{.ID}}/handle" class="j13-form j13-admin-form j13-report-handle">
<input type="hidden" name="_csrf" value="{{$.CSRF}}"/>
<label>处理备注(可选) <input name="handle_note" maxlength="500"/></label>
<label>拒绝原因(拒绝内容时必填) <input name="reject_reason" maxlength="1000"/></label>
<div class="j13-form__row">
<button type="submit" name="action" value="dismiss">驳回举报</button>
<button type="submit" name="action" value="resolve" class="j13-btn-secondary">标记已处理</button>
{{if .IsComment}}
<button type="submit" name="action" value="reject_comment">拒绝该评论</button>
{{else}}
<button type="submit" name="action" value="reject_post">拒绝该帖</button>
{{end}}
</div>
</form>
{{end}}
</li>
{{end}}
</ul>
{{if or .HasPrev .HasMore}}
<nav class="j13-pager">
{{if .HasPrev}}<a href="/admin/reports?status={{.StatusFilter}}&amp;page={{.PrevPage}}">上一页</a>{{end}}
<span>第 {{.Page}} 页</span>
{{if .HasMore}}<a href="/admin/reports?status={{.StatusFilter}}&amp;page={{.NextPage}}">下一页</a>{{end}}
</nav>
{{end}}
{{else}}
<p class="j13-empty">暂无举报。</p>
{{end}}
</main>
{{template "base/footer" .}}
{{end}}

View File

@@ -22,6 +22,28 @@
<button type="submit">{{if .Favorited}}取消收藏{{else}}收藏{{end}}</button>
</form>
{{if .CanEdit}}<a class="j13-linkbtn" href="/post/{{.PostID}}/edit">编辑</a>{{end}}
{{if .CanReportPost}}
<details class="j13-report">
<summary class="j13-linkbtn">举报</summary>
<form method="post" action="/post/{{.PostID}}/report" class="j13-report__form">
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
<label>原因
<select name="reason" required>
<option value="">请选择</option>
<option value="spam">垃圾广告</option>
<option value="abuse">人身攻击 / 辱骂</option>
<option value="illegal">违法违规</option>
<option value="irrelevant">内容无关 / 灌水</option>
<option value="other">其他</option>
</select>
</label>
<label>补充说明(可选)
<input name="detail" maxlength="500" placeholder="可选"/>
</label>
<button type="submit" class="j13-btn j13-btn--sm">提交举报</button>
</form>
</details>
{{end}}
</div>
{{end}}
</header>
@@ -59,6 +81,28 @@
{{if not $.CommentsLocked}}
<button type="button" class="j13-linkbtn j13-comment__reply-btn" data-reply-to="{{.ID}}" data-reply-floor="{{.Floor}}" data-reply-author="{{.AuthorName}}">回复</button>
{{end}}
{{if .CanReport}}
<details class="j13-report">
<summary class="j13-linkbtn">举报</summary>
<form method="post" action="/post/{{$.PostID}}/comments/{{.ID}}/report" class="j13-report__form">
<input type="hidden" name="_csrf" value="{{$.CSRF}}"/>
<label>原因
<select name="reason" required>
<option value="">请选择</option>
<option value="spam">垃圾广告</option>
<option value="abuse">人身攻击 / 辱骂</option>
<option value="illegal">违法违规</option>
<option value="irrelevant">内容无关 / 灌水</option>
<option value="other">其他</option>
</select>
</label>
<label>补充说明(可选)
<input name="detail" maxlength="500" placeholder="可选"/>
</label>
<button type="submit" class="j13-btn j13-btn--sm">提交举报</button>
</form>
</details>
{{end}}
</div>
{{end}}
</li>