fix: 修复登录重定向失效 + 404页面友好化

- ShowPage 未登录用户看未发布帖子时引导登录(携带 redirect 参数),替代直接 404
- login.js 无 redirect 参数时回退到同站 Referer 页面
- 404 页面重设计:SVG 图标 + 中文提示 + 返回首页和浏览帖子双按钮
- posts.css 新增 404 页面按钮样式
This commit is contained in:
2026-05-31 03:39:18 +08:00
parent 8b075f7387
commit e1fb28e8fb
4 changed files with 84 additions and 10 deletions

View File

@ -95,6 +95,11 @@ func (ctrl *PostController) ShowPage(c *gin.Context) {
// 仅 approved 公开可见(作者本人 + moderator+ 可预览其他状态) // 仅 approved 公开可见(作者本人 + moderator+ 可预览其他状态)
if post.Status != model.PostStatusApproved && !ctrl.postService.IsPostAccessible(uid, role, post.UserID) { if post.Status != model.PostStatusApproved && !ctrl.postService.IsPostAccessible(uid, role, post.UserID) {
// 未登录用户:引导登录后回到当前帖子
if uid == 0 {
common.RedirectToLogin(c)
return
}
c.HTML(http.StatusNotFound, "posts/404.html", common.BuildPageData(c, gin.H{ c.HTML(http.StatusNotFound, "posts/404.html", common.BuildPageData(c, gin.H{
"Title": "未找到", "Title": "未找到",
})) }))

View File

@ -3,9 +3,17 @@
{{template "layout/nav.html" .}} {{template "layout/nav.html" .}}
<div class="container"> <div class="container">
<div class="error-404"> <div class="error-404">
<h1>404</h1> <div class="error-404-icon">
<p>帖子不存在或已被删除</p> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<a href="/posts" class="btn btn-primary">返回帖子列表</a> <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
</svg>
</div>
<h1>页面未找到</h1>
<p>该帖子可能已被删除、尚未发布,或您输入的地址有误</p>
<div class="error-404-actions">
<a href="/" class="btn btn-secondary">返回首页</a>
<a href="/posts" class="btn btn-primary">浏览帖子</a>
</div>
</div> </div>
</div> </div>
{{template "layout/footer.html" .}} {{template "layout/footer.html" .}}

View File

@ -200,19 +200,67 @@
/* ========== 404 ========== */ /* ========== 404 ========== */
.error-404 { .error-404 {
text-align: center; text-align: center;
padding: 80px 0; padding: 100px 0;
max-width: 480px;
margin: 0 auto;
}
.error-404-icon {
color: #d1d5db;
margin-bottom: 24px;
}
.error-404-icon svg {
width: 72px;
height: 72px;
} }
.error-404 h1 { .error-404 h1 {
font-size: 72px; font-size: 24px;
color: #d1d5db; color: #374151;
margin: 0; margin: 0 0 8px;
font-weight: 600;
} }
.error-404 p { .error-404 p {
font-size: 18px; font-size: 15px;
color: #6b7280; color: #9ca3af;
margin: 12px 0 24px; margin: 0 0 32px;
line-height: 1.6;
}
.error-404-actions {
display: flex;
justify-content: center;
gap: 12px;
}
.error-404-actions .btn {
padding: 10px 24px;
border-radius: 8px;
font-size: 14px;
text-decoration: none;
transition: all 0.2s;
}
.error-404-actions .btn-primary {
background: #2563eb;
color: #fff;
border: none;
}
.error-404-actions .btn-primary:hover {
background: #1d4ed8;
}
.error-404-actions .btn-secondary {
background: #f3f4f6;
color: #374151;
border: 1px solid #e5e7eb;
}
.error-404-actions .btn-secondary:hover {
background: #e5e7eb;
} }
/* ========== 空状态 ========== */ /* ========== 空状态 ========== */

View File

@ -19,6 +19,19 @@
function getRedirect() { function getRedirect() {
var m = window.location.search.match(/[?&]redirect=([^&]+)/); var m = window.location.search.match(/[?&]redirect=([^&]+)/);
if (m) return decodeURIComponent(m[1]); if (m) return decodeURIComponent(m[1]);
// 回退:如果来源页是本站页面,跳回来源页
try {
var ref = document.referrer;
if (ref) {
var a = document.createElement('a');
a.href = ref;
if (a.hostname === window.location.hostname &&
a.pathname !== window.location.pathname &&
a.pathname.indexOf('/auth/') !== 0) {
return a.pathname + a.search + a.hash;
}
}
} catch (e) {}
return '/'; return '/';
} }