feat: SSR 个人闭环(profile / user / favorites)
登录用户可改资料与头像、浏览收藏;公开主页不含邮箱;改密吊销并重建本端 session。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
<nav class="j13-nav">
|
||||
{{if .LoggedIn}}
|
||||
<a href="/compose">发帖</a>
|
||||
<a href="/favorites">收藏</a>
|
||||
<a href="/profile">{{.ViewerName}}</a>
|
||||
{{if .IsAdmin}}<a href="/admin/dashboard">后台</a>{{end}}
|
||||
<form class="j13-inline-form" method="post" action="/logout">
|
||||
|
||||
@@ -2,5 +2,5 @@ package templates
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed *.tmpl base/*.tmpl home/*.tmpl post/*.tmpl shared/*.tmpl status/*.tmpl auth/*.tmpl admin/*.tmpl
|
||||
//go:embed *.tmpl base/*.tmpl home/*.tmpl post/*.tmpl shared/*.tmpl status/*.tmpl auth/*.tmpl admin/*.tmpl profile/*.tmpl user/*.tmpl favorites/*.tmpl
|
||||
var FS embed.FS
|
||||
|
||||
30
templates/favorites/list.tmpl
Normal file
30
templates/favorites/list.tmpl
Normal file
@@ -0,0 +1,30 @@
|
||||
{{define "favorites/list"}}
|
||||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<main class="j13-main j13-profile">
|
||||
<h1>我的收藏</h1>
|
||||
{{template "base/alert" .}}
|
||||
<p class="j13-muted">共 {{.Total}} 条 · <a href="/profile">个人中心</a></p>
|
||||
{{if .Items}}
|
||||
<ul class="j13-post-list">
|
||||
{{range .Items}}
|
||||
<li class="j13-post-item">
|
||||
<a class="j13-post-item__title" href="/post/{{.PostID}}">{{.Title}}</a>
|
||||
<div class="j13-post-item__meta">
|
||||
{{if .AuthorName}}<span>{{.AuthorName}}</span>{{end}}
|
||||
{{if .BoardName}}<span>{{.BoardName}}</span>{{end}}
|
||||
<span>{{.CreatedLabel}}</span>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
<nav class="j13-pager">
|
||||
{{if .HasPrev}}<a href="/favorites?page={{.PrevPage}}">上一页</a>{{end}}
|
||||
{{if .HasMore}}<a href="/favorites?page={{.NextPage}}">下一页</a>{{end}}
|
||||
</nav>
|
||||
{{else}}
|
||||
<p class="j13-empty">还没有收藏。在帖子详情页可点击收藏。</p>
|
||||
{{end}}
|
||||
</main>
|
||||
{{template "base/footer" .}}
|
||||
{{end}}
|
||||
@@ -7,7 +7,7 @@
|
||||
{{if .Featured}}<span class="j13-tag j13-tag--feat">精华</span>{{end}}
|
||||
{{if .PostTypeLabel}}<span class="j13-tag">{{.PostTypeLabel}}</span>{{end}}
|
||||
{{if .BoardName}}<a class="j13-tag" href="/board/{{.BoardID}}">{{.BoardName}}</a>{{end}}
|
||||
<span>{{.AuthorName}}</span>
|
||||
{{if .AuthorID}}<a href="/user/{{.AuthorID}}">{{.AuthorName}}</a>{{else}}<span>{{.AuthorName}}</span>{{end}}
|
||||
<span>{{.CreatedLabel}}</span>
|
||||
<span>{{.ViewCount}} 阅读</span>
|
||||
</div>
|
||||
@@ -38,7 +38,7 @@
|
||||
<li class="j13-comment" id="floor-{{.Floor}}">
|
||||
<div class="j13-comment__meta">
|
||||
<span class="j13-comment__floor">#{{.Floor}}</span>
|
||||
<span>{{.AuthorName}}</span>
|
||||
{{if .AuthorID}}<a href="/user/{{.AuthorID}}">{{.AuthorName}}</a>{{else}}<span>{{.AuthorName}}</span>{{end}}
|
||||
<span>{{.CreatedLabel}}</span>
|
||||
</div>
|
||||
{{if .ContentHidden}}
|
||||
|
||||
72
templates/profile/view.tmpl
Normal file
72
templates/profile/view.tmpl
Normal file
@@ -0,0 +1,72 @@
|
||||
{{define "profile/view"}}
|
||||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<main class="j13-main j13-profile">
|
||||
<h1>个人中心</h1>
|
||||
{{template "base/alert" .}}
|
||||
<p class="j13-muted">
|
||||
<a href="{{.PublicURL}}">查看公开主页</a>
|
||||
· <a href="/favorites">我的收藏</a>
|
||||
</p>
|
||||
|
||||
<ul class="j13-admin-stats">
|
||||
<li><strong>{{.PostCount}}</strong><span>帖子</span></li>
|
||||
<li><strong>{{.CommentCount}}</strong><span>评论</span></li>
|
||||
<li><strong>{{.FavoriteCount}}</strong><span>收藏</span></li>
|
||||
<li><strong>{{.LikeReceived}}</strong><span>获赞</span></li>
|
||||
</ul>
|
||||
|
||||
<section class="j13-profile__card">
|
||||
<h2>账号</h2>
|
||||
<p>用户名 <strong>{{.Username}}</strong></p>
|
||||
<p class="j13-muted">邮箱 {{.Email}}</p>
|
||||
<p class="j13-muted">等级 Lv.{{.Level}} · 经验 {{.Exp}} · 积分 {{.Points}}</p>
|
||||
{{if .Avatar}}
|
||||
<p><img class="j13-avatar" src="{{.Avatar}}" alt="头像"/></p>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>头像</h2>
|
||||
<form method="post" action="/profile/avatar" enctype="multipart/form-data" class="j13-form j13-admin-form">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
|
||||
<label>图片(最大 {{.AvatarMaxMB}} MB)
|
||||
<input type="file" name="avatar" accept="image/*" required/>
|
||||
</label>
|
||||
<button type="submit">上传头像</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>昵称</h2>
|
||||
<form method="post" action="/profile/nickname" class="j13-form j13-admin-form">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
|
||||
<label>昵称 <input name="nickname" value="{{.Nickname}}" maxlength="32" required/></label>
|
||||
<button type="submit">保存昵称</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>签名</h2>
|
||||
<form method="post" action="/profile/signature" class="j13-form j13-admin-form">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
|
||||
<label>签名
|
||||
<textarea name="signature" rows="3" maxlength="{{.SignatureMax}}">{{.Signature}}</textarea>
|
||||
</label>
|
||||
<button type="submit">保存签名</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>修改密码</h2>
|
||||
<form method="post" action="/profile/password" class="j13-form j13-admin-form">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
|
||||
<label>当前密码 <input type="password" name="old_password" required autocomplete="current-password"/></label>
|
||||
<label>新密码 <input type="password" name="new_password" required minlength="6" autocomplete="new-password"/></label>
|
||||
<label>确认新密码 <input type="password" name="new_password2" required minlength="6" autocomplete="new-password"/></label>
|
||||
<button type="submit">更新密码</button>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
{{template "base/footer" .}}
|
||||
{{end}}
|
||||
48
templates/user/view.tmpl
Normal file
48
templates/user/view.tmpl
Normal file
@@ -0,0 +1,48 @@
|
||||
{{define "user/view"}}
|
||||
{{template "base/head" .}}
|
||||
{{template "base/navbar" .}}
|
||||
<main class="j13-main j13-profile">
|
||||
<header class="j13-user-hero">
|
||||
{{if .Avatar}}
|
||||
<img class="j13-avatar j13-avatar--lg" src="{{.Avatar}}" alt=""/>
|
||||
{{else}}
|
||||
<span class="j13-avatar j13-avatar--lg j13-avatar--placeholder" aria-hidden="true">·</span>
|
||||
{{end}}
|
||||
<div>
|
||||
<h1>{{if .Nickname}}{{.Nickname}}{{else}}{{.Username}}{{end}}</h1>
|
||||
<p class="j13-muted">@{{.Username}} · Lv.{{.Level}} · 积分 {{.Points}}</p>
|
||||
{{if .Signature}}<p class="j13-user-sig">{{.Signature}}</p>{{end}}
|
||||
{{if .IsSelf}}<p><a href="/profile">编辑资料</a></p>{{end}}
|
||||
</div>
|
||||
</header>
|
||||
{{template "base/alert" .}}
|
||||
|
||||
<ul class="j13-admin-stats">
|
||||
<li><strong>{{.PostCount}}</strong><span>帖子</span></li>
|
||||
<li><strong>{{.CommentCount}}</strong><span>评论</span></li>
|
||||
<li><strong>{{.LikeReceived}}</strong><span>获赞</span></li>
|
||||
</ul>
|
||||
|
||||
<h2>最近帖子</h2>
|
||||
{{if .Posts}}
|
||||
<ul class="j13-post-list">
|
||||
{{range .Posts}}
|
||||
<li class="j13-post-item">
|
||||
<a class="j13-post-item__title" href="/post/{{.ID}}">{{.Title}}</a>
|
||||
<div class="j13-post-item__meta">
|
||||
{{if .BoardName}}<span>{{.BoardName}}</span>{{end}}
|
||||
<span>{{.CreatedLabel}}</span>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
<nav class="j13-pager">
|
||||
{{if .HasPrev}}<a href="/user/{{.UserID}}?page={{.PrevPage}}">上一页</a>{{end}}
|
||||
{{if .HasMore}}<a href="/user/{{.UserID}}?page={{.NextPage}}">下一页</a>{{end}}
|
||||
</nav>
|
||||
{{else}}
|
||||
<p class="j13-empty">暂无公开帖子。</p>
|
||||
{{end}}
|
||||
</main>
|
||||
{{template "base/footer" .}}
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user