Files
mce/templates/MetaLab-2026/html/studio/posts.html
Victor_Jay 6c9a4414cb refactor: 全局移除浏览器 alert 弹窗,统一使用页面内 showToast 通知
- 替换全部 11 个文件中 36 处 alert() 为 showToast()
- API 错误/异常使用 showToast(msg, 'error'),3秒自动消失
- 表单校验提示使用 showToast(msg, 'warning'),3秒自动消失
- 成功确认使用 showToast(msg, 'success'),3秒自动消失
- 移除 post-energize.js 中与全局 showToast 冲突的本地实现
- 删除 posts.css 中已失去引用的 .energize-toast 样式
- 保留 showConfirm() 自定义确认弹窗(需用户确认的操作)
2026-06-03 01:25:12 +08:00

116 lines
4.6 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="studio-wrapper">
{{template "studio/sidebar.html" .}}
<main class="studio-main">
<div class="studio-header">
<h1>内容管理</h1>
{{if .Overview}}
<div class="header-counts">
<span class="header-count approved">已发布 {{.Overview.ApprovedCount}}</span>
<span class="header-count pending">审核中 {{.Overview.PendingCount}}</span>
<span class="header-count draft">草稿 {{.Overview.DraftCount}}</span>
<span class="header-count rejected">已退回 {{.Overview.RejectedCount}}</span>
</div>
{{end}}
</div>
{{if .Error}}
<div class="studio-error">{{.Error}}</div>
{{else}}
<!-- 状态筛选 tabs -->
<div class="status-tabs">
<a href="/studio/posts" class="status-tab {{if not .CurrentStatus}}active{{end}}">全部</a>
<a href="/studio/posts?status=approved" class="status-tab {{if eq .CurrentStatus "approved"}}active{{end}}">已发布</a>
<a href="/studio/posts?status=pending" class="status-tab {{if eq .CurrentStatus "pending"}}active{{end}}">审核中</a>
<a href="/studio/posts?status=draft" class="status-tab {{if eq .CurrentStatus "draft"}}active{{end}}">草稿</a>
<a href="/studio/posts?status=rejected" class="status-tab {{if eq .CurrentStatus "rejected"}}active{{end}}">已退回</a>
</div>
{{if .Posts}}
<div class="post-list">
{{range .Posts}}
<div class="post-item">
<div class="post-item-main">
<a href="/posts/{{.ID}}" class="post-item-title" target="_blank">{{.Title}}</a>
<div class="post-item-meta">
<span class="post-status-badge status-{{.Status}}">{{index $.StatusNames .Status}}</span>
{{if .IsLocked}}<span class="post-status-badge status-locked">已锁定</span>{{end}}
<span>{{.CreatedAt.Format "2006-01-02 15:04"}}</span>
{{if .RejectReason}}
<span class="post-reject-hint">退回理由:{{.RejectReason}}</span>
{{end}}
</div>
</div>
<div class="post-item-actions">
{{if not .IsLocked}}<a href="/studio/write?id={{.ID}}" class="action-btn">编辑</a>{{end}}
<a href="/posts/{{.ID}}" target="_blank" class="action-btn">查看</a>
<button class="action-btn danger" data-post-id="{{.ID}}" data-action="delete" title="删除">删除</button>
</div>
</div>
{{end}}
</div>
<!-- 分页 -->
{{if gt .TotalPages 1}}
<div class="pagination">
{{if gt .Page 1}}
<a href="/studio/posts?status={{$.CurrentStatus}}&page={{subtract .Page 1}}" class="page-btn">上一页</a>
{{end}}
<span class="page-info">第 {{.Page}} / {{.TotalPages}} 页(共 {{.Total}} 篇)</span>
{{if lt .Page .TotalPages}}
<a href="/studio/posts?status={{$.CurrentStatus}}&page={{add .Page 1}}" class="page-btn">下一页</a>
{{end}}
</div>
{{end}}
{{else}}
<div class="studio-empty">
<p>还没有{{if .CurrentStatus}}{{index $.StatusNames .CurrentStatus}}{{end}}内容的文章</p>
<a href="/studio/write" class="btn-primary">去写一篇</a>
</div>
{{end}}
{{end}}
</main>
</div>
<script nonce="{{.CSPNonce}}">
function deletePost(id) {
showConfirm('确认', '确定要删除这篇文章吗?').then(function(ok) {
if (!ok) return;
fetch('/api/studio/posts/' + id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': getCSRFToken()
}
})
.then(r => r.json())
.then(data => {
if (data.success) {
location.reload();
} else {
showToast(data.message || '删除失败', 'error');
}
});
});
}
// 事件委托代替内联 onclick满足 CSP 无 unsafe-inline
document.addEventListener('click', function(e) {
var btn = e.target.closest('[data-action="delete"]');
if (btn) {
deletePost(btn.getAttribute('data-post-id'));
}
});
</script>
{{template "layout/footer.html" .}}
</body>
</html>