- 拆分 926 行内联 JS 为 5 个独立模块文件 - post-view.js: Vditor 渲染 + 提交审核按钮 (~50 行) - post-energize.js: 赋能按钮 + 弹窗 (~76 行) - post-reactions.js: 赞/踩系统 (~71 行) - post-favorite.js: 收藏按钮 + 收藏夹弹窗 (~218 行) - post-comments.js: 评论系统 (~456 行) - show.html 从 1080 行缩减至 159 行
159 lines
8.4 KiB
HTML
159 lines
8.4 KiB
HTML
{{template "layout/header.html" .}}
|
|
<body>
|
|
|
|
{{template "layout/nav.html" .}}
|
|
|
|
<div class="container post-detail">
|
|
<article class="post-article">
|
|
<header class="post-detail-header">
|
|
<h1 class="post-detail-title">{{.Post.Title}}</h1>
|
|
<div class="post-detail-meta">
|
|
<span class="post-author">{{if .Post.AuthorName}}{{.Post.AuthorName}}{{else}}该用户已注销{{end}}</span>
|
|
<span class="post-time">{{.Post.CreatedAt.Format "2006-01-02 15:04"}}</span>
|
|
{{if ne .Post.Status "approved"}}
|
|
<span class="post-status post-status-{{.Post.Status}}">{{index $.StatusNames .Post.Status}}</span>
|
|
{{end}}
|
|
{{if .Post.IsLocked}}
|
|
<span class="post-status post-status-locked">已锁定</span>
|
|
{{end}}
|
|
{{if and .Post.PendingBody (eq $.Post.UserID $.UID)}}
|
|
<span class="post-status post-status-revision">修订审核中</span>
|
|
{{end}}
|
|
</div>
|
|
</header>
|
|
|
|
{{if .Post.RejectReason}}
|
|
<div class="post-reject-reason">
|
|
<strong>退回理由:</strong>{{.Post.RejectReason}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="post-detail-body" id="postContent"></div>
|
|
</article>
|
|
|
|
<!-- 赞/踩/收藏按钮 -->
|
|
<div class="post-reactions" id="postReactions" data-post-id="{{.Post.ID}}">
|
|
<button class="reaction-btn reaction-like-btn" id="likeBtn" title="点赞">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>
|
|
<span class="reaction-like-count" id="likesCount">{{.Post.LikesCount}}</span>
|
|
</button>
|
|
<button class="reaction-btn reaction-dislike-btn" id="dislikeBtn" title="踩">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3H10zM17 2h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"/></svg>
|
|
</button>
|
|
<button class="reaction-btn reaction-fav-btn" id="favBtn" title="收藏">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
|
|
<span class="reaction-like-count" id="favCount">{{.Post.FavoritesCount}}</span>
|
|
</button>
|
|
</div>
|
|
|
|
{{if .IsLoggedIn}}
|
|
<div class="post-actions">
|
|
{{if and $.Post (or (eq $.Post.UserID $.UID) $.CanAccessAdmin) (ne $.Post.Status "pending") (not $.Post.IsLocked)}}
|
|
<a href="/studio/write?id={{$.Post.ID}}" class="btn btn-secondary">编辑</a>
|
|
{{end}}
|
|
{{if and $.Post (eq $.Post.UserID $.UID) (or (eq $.Post.Status "draft") (eq $.Post.Status "rejected")) (not $.Post.IsLocked)}}
|
|
<button class="btn btn-primary" id="submitAuditBtn" data-id="{{$.Post.ID}}">提交审核</button>
|
|
{{end}}
|
|
{{if and $.Post (ne $.Post.UserID $.UID)}}
|
|
<button class="btn btn-primary" id="energizeBtn" data-id="{{$.Post.ID}}">赋能</button>
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- 赋能弹窗 -->
|
|
<div class="energize-overlay" id="energizeOverlay" style="display:none">
|
|
<div class="energize-modal">
|
|
<div class="energize-modal-header">
|
|
<h3>为这篇文章注入能量</h3>
|
|
<button class="energize-close" id="energizeClose">×</button>
|
|
</div>
|
|
<div class="energize-modal-body">
|
|
<p class="energize-hint" id="energizeCapHint" style="display:none">
|
|
今日赋能经验奖励已达上限,继续赋能将消耗域能,对方仍会获得激励。
|
|
</p>
|
|
<div class="energize-options">
|
|
<button class="energize-option-btn" id="energizeLight" data-amount="10">
|
|
<span class="energize-option-title">轻赋</span>
|
|
<span class="energize-option-cost">消耗 1 域能</span>
|
|
<span class="energize-option-gain">获得 10 经验</span>
|
|
</button>
|
|
<button class="energize-option-btn" id="energizeHeavy" data-amount="20">
|
|
<span class="energize-option-title">重赋</span>
|
|
<span class="energize-option-cost">消耗 2 域能</span>
|
|
<span class="energize-option-gain">获得 20 经验</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 选择收藏夹弹窗 -->
|
|
<div class="fav-overlay" id="favOverlay" style="display:none">
|
|
<div class="fav-modal">
|
|
<div class="fav-modal-header">
|
|
<h3>选择收藏夹</h3>
|
|
<button class="fav-close" id="favClose">×</button>
|
|
</div>
|
|
<div class="fav-modal-body">
|
|
<div class="fav-folder-list" id="favFolderCheckList">
|
|
<div class="fav-loading">加载中...</div>
|
|
</div>
|
|
<div class="fav-new-folder">
|
|
<input type="text" class="fav-new-input" id="favNewInput" placeholder="新建收藏夹..." maxlength="50">
|
|
<button class="fav-new-btn" id="favNewConfirm">创建并收藏</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- 评论区 -->
|
|
{{if .Post.AllowComment}}
|
|
<section class="comments-section" id="comments">
|
|
<h3 class="comments-title">评论 <span class="comments-count" id="commentsTotal">0</span></h3>
|
|
|
|
{{if .IsLoggedIn}}
|
|
<div class="comment-form">
|
|
<textarea class="comment-input" id="commentInput" placeholder="写下你的评论..." rows="3" maxlength="5000"></textarea>
|
|
<div class="comment-form-actions">
|
|
<label class="comment-upload-btn" id="commentUploadLabel">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
|
|
图片
|
|
</label>
|
|
<input type="file" id="commentImageInput" accept="image/*" style="display:none" />
|
|
<button class="btn btn-primary comment-submit-btn" id="commentSubmitBtn">发表评论</button>
|
|
</div>
|
|
<div class="comment-upload-preview" id="commentUploadPreview"></div>
|
|
</div>
|
|
{{else}}
|
|
<div class="comment-login-hint">
|
|
<a href="/auth/login?redirect=/posts/{{$.Post.ID}}">登录</a> 后参与评论
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="comments-list" id="commentsList"></div>
|
|
<div class="comments-loading" id="commentsLoading" style="display:none">加载中...</div>
|
|
<button class="btn btn-secondary comments-load-more" id="commentsLoadMore" style="display:none">加载更多</button>
|
|
</section>
|
|
{{end}}
|
|
|
|
<!-- @ 提及下拉 -->
|
|
<div class="mention-dropdown" id="mentionDropdown" style="display:none"></div>
|
|
</div>
|
|
|
|
{{template "layout/footer.html" .}}
|
|
|
|
{{/* MD 内容安全传递给 JS */}}
|
|
<textarea id="postMdContent" style="display:none">{{.Post.Body}}</textarea>
|
|
|
|
<link rel="stylesheet" href="/static/vditor/dist/index.css?v={{assetV "/static/vditor/dist/index.css"}}">
|
|
<script src="/static/vditor/dist/method.min.js?v={{assetV "/static/vditor/dist/method.min.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/common.js?v={{assetV "/static/js/common.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/shortcode.js?v={{assetV "/static/js/shortcode.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/post-view.js?v={{assetV "/static/js/post-view.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/post-energize.js?v={{assetV "/static/js/post-energize.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/post-reactions.js?v={{assetV "/static/js/post-reactions.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/post-favorite.js?v={{assetV "/static/js/post-favorite.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/post-comments.js?v={{assetV "/static/js/post-comments.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
</body>
|
|
</html>
|