Files
mce/templates/MetaLab-2026/html/posts/show.html
Victor_Jay 89fa50a013 fix: 锁定机制不再改变帖子状态,锁定与退回独立
- Post 模型新增 IsLocked 字段,与 Status 解耦
- Lock 仅设 IsLocked=true(不改 Status),已通过帖子锁定后仍公开可见
- Unlock 仅设 IsLocked=false(不改 Status)
- Update/EditPage 编辑检查改用 IsLocked 而非 Status==locked
- Reject 与 Lock 独立,可单独退回或锁定+退回组合使用
- 新增 ErrPostCannotLock 错误哨兵
- 前端模板编辑按钮/锁定标识基于 IsLocked 渲染
2026-05-30 20:08:41 +08:00

109 lines
3.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{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}}
</div>
</header>
<div class="post-detail-body" id="postContent"></div>
{{if .Post.RejectReason}}
<div class="post-reject-reason">
<strong>退回理由:</strong>{{.Post.RejectReason}}
</div>
{{end}}
</article>
{{if .IsLoggedIn}}
<div class="post-actions">
{{if and $.Post (or (eq $.Post.UserID $.UID) $.CanAccessAdmin) (ne $.Post.Status "pending") (not $.Post.IsLocked)}}
<a href="/posts/{{$.Post.ID}}/edit" class="btn btn-secondary">编辑</a>
{{end}}
{{if and $.Post (eq $.Post.UserID $.UID) (or (eq $.Post.Status "draft") (eq $.Post.Status "rejected"))}}
<button class="btn btn-primary" id="submitAuditBtn" data-id="{{$.Post.ID}}">提交审核</button>
{{end}}
</div>
{{end}}
</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">
<script src="/static/vditor/dist/method.min.js"></script>
<script src="/static/js/common.js"></script>
<script src="/static/js/shortcode.js"></script>
<script>
(function() {
var el = document.getElementById('postContent');
var mdEl = document.getElementById('postMdContent');
if (!el || !mdEl) return;
var md = mdEl.value;
Vditor.preview(el, md, {
cdn: '/static/vditor',
theme: { current: 'light', path: '/static/vditor/dist/css/content-theme' },
hljs: { style: 'github-dark', enable: true },
after: function() {
// 外部链接自动加 nofollow + target="_blank",避免权重流失
var host = window.location.host;
var links = el.querySelectorAll('a[href^="http"]');
for (var i = 0; i < links.length; i++) {
var a = links[i];
if (a.host && a.host !== host) {
a.setAttribute('rel', 'nofollow noopener noreferrer');
a.setAttribute('target', '_blank');
}
}
}
});
// Vditor.preview() 渲染 MDshortcode 占位 div 原样保留
// 渲染完成后,将占位 div 替换为对应卡片 UI
renderShortcodes(el);
})();
</script>
<script>
// 提交审核按钮
(function() {
var btn = document.getElementById('submitAuditBtn');
if (!btn) return;
btn.addEventListener('click', function() {
if (!confirm('确认提交审核?审核通过后将公开发布。')) return;
var csrf = document.querySelector('meta[name="csrf-token"]');
fetch('/api/posts/' + btn.dataset.id + '/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrf ? csrf.getAttribute('content') : ''
}
})
.then(function(r) { return r.json(); })
.then(function(d) {
if (d.success) { window.location.reload(); }
else { alert(d.message || '提交失败'); }
})
.catch(function() { alert('请求失败'); });
});
})();
</script>
</body>
</html>