分类:Model/Repo/Service/Controller + 管理后台树形页面 + 首页导航栏
标签:Model/Repo/Service/Controller + /tags/{slug} 落地页 + 写文章页输入
Post 加 CategoryID,Create/Update 支持分类和标签
SQL 迁移含 categories/tags/post_tags 表及预设未分类
149 lines
7.7 KiB
HTML
149 lines
7.7 KiB
HTML
{{template "layout/header.html" .}}
|
|
<body>
|
|
|
|
{{template "layout/nav.html" .}}
|
|
|
|
<div class="studio-wrapper">
|
|
{{template "studio/sidebar.html" .}}
|
|
|
|
<main class="studio-main">
|
|
<div class="editor-layout">
|
|
{{if and .Post .Post.IsLocked}}
|
|
<div class="studio-locked-banner">
|
|
<div class="locked-banner-icon">🔒</div>
|
|
<div>
|
|
<strong>这篇文章已被锁定,无法编辑。</strong>
|
|
{{if .Post.LockReason}}
|
|
<p>锁定理由:{{.Post.LockReason}}</p>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{if and (not .Post) (lt .Exp 1)}}
|
|
<div class="studio-locked-banner">
|
|
<div class="locked-banner-icon">🔒</div>
|
|
<div>
|
|
<strong>Lv1 解锁投稿</strong>
|
|
<p>完成首次任务(设置用户名、上传头像)或参与社区互动以获取经验。</p>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<form id="postForm" class="editor-form">
|
|
<input type="hidden" id="postId" value="{{if .Post}}{{.Post.ID}}{{end}}">
|
|
{{if .Post}}
|
|
<input type="hidden" id="isLocked" value="{{if .Post.IsLocked}}1{{else}}0{{end}}">
|
|
<textarea id="editBody" style="display:none">{{.Post.Body}}</textarea>
|
|
{{end}}
|
|
|
|
<div class="editor-header">
|
|
<input type="text" id="postTitle" class="editor-title-input"
|
|
value="{{if .Post}}{{.Post.Title}}{{end}}"
|
|
placeholder="输入文章标题..."
|
|
maxlength="200" required autofocus
|
|
{{if and .Post .Post.IsLocked}}disabled{{end}}>
|
|
</div>
|
|
|
|
<!-- 文章属性面板 -->
|
|
<div class="editor-meta"{{if and .Post .Post.IsLocked}} style="opacity:0.5;pointer-events:none"{{end}}>
|
|
<div class="meta-row">
|
|
<span class="meta-label">可见性</span>
|
|
<label class="meta-radio"><input type="radio" name="visibility" value="public" checked> 公开</label>
|
|
<label class="meta-radio"><input type="radio" name="visibility" value="private"> 私密</label>
|
|
</div>
|
|
<div class="meta-row">
|
|
<span class="meta-label">类型</span>
|
|
<label class="meta-radio"><input type="radio" name="post_type" value="original" checked> 原创</label>
|
|
<label class="meta-radio"><input type="radio" name="post_type" value="reprint"> 转载</label>
|
|
<span id="reprintSourceArea" style="display:none;margin-left:8px">
|
|
<input type="text" id="reprintSource" placeholder="转载来源" style="width:260px">
|
|
</span>
|
|
</div>
|
|
<div class="meta-row" id="reprintProhibitArea">
|
|
<span class="meta-label"></span>
|
|
<label class="meta-checkbox"><input type="checkbox" id="reprintProhibited"> 未经作者许可,禁止转载</label>
|
|
</div>
|
|
<div class="meta-row">
|
|
<span class="meta-label">分类</span>
|
|
<select id="categoryId" style="width:auto">
|
|
<option value="">(未分类)</option>
|
|
{{range .Categories}}
|
|
<option value="{{.ID}}" {{if and $.Post $.Post.CategoryID}}{{if eq .ID (derefUint $.Post.CategoryID)}}selected{{end}}{{end}}>{{.Name}}</option>
|
|
{{end}}
|
|
</select>
|
|
</div>
|
|
<div class="meta-row">
|
|
<span class="meta-label">标签</span>
|
|
<input type="text" id="tagInput" placeholder="逗号分隔,最多 10 个" style="width:300px">
|
|
</div>
|
|
<div class="meta-row">
|
|
<span class="meta-label">声明</span>
|
|
<select id="declaration" style="width:auto">
|
|
<option value="">(无特别声明)</option>
|
|
<option value="ai_generated">AI 辅助创作</option>
|
|
<option value="fictional">含虚构情节</option>
|
|
<option value="speculative">含猜测性内容</option>
|
|
<option value="disturbing">可能令人不适</option>
|
|
<option value="spoiler">含剧透内容</option>
|
|
<option value="controversial">涉及争议性话题</option>
|
|
<option value="opinion">个人观点</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="editor-main">
|
|
<div class="editor-pane">
|
|
<div id="vditor"></div>
|
|
</div>
|
|
<aside class="editor-sidebar">
|
|
<div class="editor-sidebar-section">
|
|
<h4>快捷语法</h4>
|
|
<ul class="tips-list">
|
|
<li><code>#</code> <code>##</code> <code>###</code> 标题</li>
|
|
<li><code>**粗体**</code> <code>*斜体*</code></li>
|
|
<li><code>`行内代码`</code></li>
|
|
<li><code>```</code> 代码块</li>
|
|
<li><code>></code> 引用</li>
|
|
<li><code>-</code> 无序列表</li>
|
|
<li><code>[文字](链接)</code></li>
|
|
<li><code></code></li>
|
|
</ul>
|
|
</div>
|
|
<div class="editor-sidebar-section">
|
|
<h4>发布提示</h4>
|
|
<ul class="tips-list">
|
|
<li>标题控制在 50 字以内</li>
|
|
<li>正文清晰分段,便于阅读</li>
|
|
<li>代码使用代码块包裹</li>
|
|
<li>Ctrl+S 快速提交</li>
|
|
</ul>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
|
|
<div class="editor-statusbar">
|
|
<span class="status-item" id="wordCount">0 字</span>
|
|
<span class="status-item status-draft" id="draftStatus" style="display:none">草稿已保存</span>
|
|
<span class="status-spacer"></span>
|
|
{{if and .Post .Post.IsLocked}}
|
|
<span class="locked-submit-hint">🔒 此文已锁定,无法修改</span>
|
|
{{else if and (not .Post) (lt .Exp 1)}}
|
|
<span class="locked-submit-hint">🔒 Lv1 解锁投稿</span>
|
|
{{else}}
|
|
<button type="submit" class="btn btn-primary btn-submit">{{if .Post}}保存修改{{else}}发布帖子{{end}}</button>
|
|
{{end}}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
{{template "layout/footer.html" .}}
|
|
|
|
<link rel="stylesheet" href="/static/vditor/dist/index.css?v={{assetV "/static/vditor/dist/index.css"}}">
|
|
<script src="/static/vditor/dist/index.min.js?v={{assetV "/static/vditor/dist/index.min.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
<script src="/static/js/studio-editor.js?v={{assetV "/static/js/studio-editor.js"}}" nonce="{{.CSPNonce}}"></script>
|
|
</body>
|
|
</html>
|