Files
mce/templates/MetaLab-2026/html/posts/show.html
Victor_Jay eabc1e7d3d feat: 已发布帖子编辑后进修订审核,通过前保持展示旧内容
- Post 模型新增 PendingTitle/PendingBody 字段,分离已发布内容与待审修订
- Update: approved 帖子编辑写入 Pending 字段,不覆盖正文,不改变发布状态
- Approve: 有 PendingBody 时复制到正式字段后清空,无 PendingBody 走首次审核
- Reject: 有 PendingBody 时仅清空待审修订(保持已发布),无 PendingBody 走普通退回
- 新增 ListPendingRevisions 查询,管理后台独立展示"修订待审核"区域
- 详情页展示"修订审核中"标识,编辑页加载待审内容
- 通过修订后直接覆盖,不保留历史版本
2026-05-30 20:24:43 +08:00

112 lines
4.1 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}}
{{if .Post.PendingBody}}
<span class="post-status post-status-revision">修订审核中</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>