Simplify admin publishing pipeline

This commit is contained in:
yarnom 2026-06-03 18:18:50 +08:00
parent 13e7e4026d
commit 9186801c7f
37 changed files with 750 additions and 3367 deletions

View file

@ -35,6 +35,10 @@
<span>/</span>
@if (view === 'list') {
<span>文章</span>
} @else if (view === 'logs') {
<button type="button" (click)="backToList()">文章</button>
<span>/</span>
<span>日志</span>
} @else {
<button type="button" (click)="backToList()">文章</button>
<span>/</span>
@ -45,6 +49,7 @@
<details class="user-menu">
<summary>{{ user.username }}</summary>
<div class="user-menu-panel">
<button type="button" (click)="showLogs()">日志</button>
<button type="button" (click)="logout()">退出</button>
</div>
</details>
@ -135,6 +140,82 @@
</span>
<button type="button" class="link-button" [disabled]="page >= totalPages" (click)="nextPage()">
下一页 →
</button>
</nav>
</section>
} @else if (view === 'logs') {
<section class="list-view">
<div class="page-heading">
<div>
<p class="eyebrow">Audit</p>
<h1>操作日志</h1>
</div>
<div class="page-actions log-actions">
<input
name="auditQuery"
placeholder="搜索用户、动作、资源、详情"
[(ngModel)]="auditQuery"
(keyup.enter)="changeAuditFilter()"
/>
<select aria-label="日志动作" [(ngModel)]="auditActionFilter" (change)="changeAuditFilter()">
<option value="">全部动作</option>
<option value="login">登录</option>
<option value="login_failed">登录失败</option>
<option value="logout">退出</option>
<option value="post_create">新建文章</option>
<option value="post_update">修改文章</option>
<option value="post_delete">删除文章</option>
<option value="post_publish">发布文章</option>
<option value="build_create">提交构建</option>
<option value="slug_generate">生成 Slug</option>
</select>
<select aria-label="资源类型" [(ngModel)]="auditResourceFilter" (change)="changeAuditFilter()">
<option value="">全部资源</option>
<option value="user">用户</option>
<option value="post">文章</option>
<option value="build_job">构建</option>
</select>
<button type="button" (click)="changeAuditFilter()">查询</button>
</div>
</div>
<div class="post-table log-table">
@if (auditLogs.length === 0) {
<p class="empty-message">暂无日志</p>
} @else {
<div class="log-table-head">
<span>时间</span>
<span>用户</span>
<span>动作</span>
<span>资源</span>
<span>详情</span>
<span>IP</span>
</div>
@for (log of auditLogs; track log.id) {
<div class="log-table-row">
<span>{{ formatDate(log.createdAt) }}</span>
<span>{{ log.actorUsername || '匿名' }}</span>
<span>{{ actionText(log.action) }}</span>
<span>{{ log.resourceType || '-' }} {{ log.resourceId || '' }}</span>
<span class="log-details">{{ detailsText(log) }}</span>
<span>{{ log.ipAddress || '-' }}</span>
</div>
}
}
</div>
<nav class="pagination" aria-label="日志分页">
<button type="button" class="link-button" [disabled]="auditPage <= 1" (click)="previousAuditPage()">
← 上一页
</button>
<span>第 {{ auditPage }} / {{ totalAuditPages }} 页,共 {{ totalAuditLogs }} 条</span>
<button
type="button"
class="link-button"
[disabled]="auditPage >= totalAuditPages"
(click)="nextAuditPage()"
>
下一页 →
</button>
</nav>
</section>
@ -152,10 +233,6 @@
</h1>
</div>
<div class="editor-actions">
<label class="upload-button">
{{ uploadingAsset ? '上传中' : '上传图片' }}
<input type="file" accept="image/*" [disabled]="uploadingAsset" (change)="uploadAsset($event)" />
</label>
<button type="submit" class="save-button" [disabled]="saving">{{ saving ? '保存中' : '保存' }}</button>
<button type="button" class="build-button" (click)="buildPost()">构建</button>
</div>
@ -248,7 +325,6 @@
<div class="markdown-workspace" [class.split]="editorMode === 'split'">
@if (editorMode !== 'preview') {
<textarea
#bodyTextarea
name="bodyMarkdown"
spellcheck="false"
[(ngModel)]="draft.bodyMarkdown"