Files
go_blog/templates/admin/article_list.html
kevin 5b227b71ef feat: 文章 CRUD 接口 JSON 化——/api/admin|my/articles
- article.go:articleForm 加 json tags,新增 parseArticleFormJSON(绑定+
  去白);ArticleCreate/ArticleUpdate/ArticleDelete 增加 redirectPath 参数,
  校验失败改 APIError 400、DB 错误 500,成功 {ok,redirect}(原 renderForm
  分支移除);id 改用 parseUintParam 数值化
- my_articles.go:MyArticleCreate 复用 ArticleCreate(db, /my/articles);
  MyArticleUpdate/MyArticleDelete 保留 author_id 所有权约束(404
  article_not_found);my 更新不触碰标签(表单无该字段,与旧行为一致)
- main.go:admin/my 文章旧 POST 路由移除,改 POST/PUT/DELETE
  /api/admin/articles[/:id] 与 /api/my/articles[/:id]
- 模板:article_create.html/my_article_form.html 表单改 blogAPI 提交
  (easyMDE.value() 同步正文、editor e.submitter 分流草稿/发布),错误内联
  articleError/myArticleError;article_list.html/my_articles.html 删除改
  blogDelete 委托(base.html 新公共函数,DELETE + reload 保筛选状态)
- main_test 冒烟补文章 CRUD 断言;go build/vet/test 全绿
2026-08-27 19:40:02 +08:00

63 lines
3.6 KiB
HTML

{{define "article_list"}}
{{template "header" .}}
<section class="max-w-5xl mx-auto px-4 py-12">
<div class="flex items-center justify-between mb-8">
<h2 class="text-3xl font-bold text-gray-900">{{index .Tr "article_list_title"}}</h2>
<a href="/admin/articles/new"
class="inline-flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg font-medium hover:bg-blue-700 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
</svg>
{{index .Tr "dash_new_article"}}
</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<table class="w-full text-left">
<thead class="bg-gray-50 border-b border-gray-200">
<tr>
<th class="px-4 py-3 text-sm font-semibold text-gray-600">{{index .Tr "article_col_title"}}</th>
<th class="px-4 py-3 text-sm font-semibold text-gray-600">{{index .Tr "article_col_status"}}</th>
<th class="px-4 py-3 text-sm font-semibold text-gray-600">{{index .Tr "article_col_published"}}</th>
<th class="px-4 py-3 text-sm font-semibold text-gray-600 text-right">{{index .Tr "article_col_actions"}}</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
{{range .Articles}}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm text-gray-800">
{{.Title}}
{{if .IsTop}}<span class="ml-1 text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">{{index $.Tr "article_is_top"}}</span>{{end}}
</td>
<td class="px-4 py-3 text-sm">
{{if eq .Status 1}}<span class="text-xs bg-green-100 text-green-700 px-2 py-1 rounded">{{index $.Tr "article_published"}}</span>
{{else if eq .Status 2}}<span class="text-xs bg-gray-200 text-gray-600 px-2 py-1 rounded">{{index $.Tr "article_archived"}}</span>
{{else}}<span class="text-xs bg-yellow-100 text-yellow-700 px-2 py-1 rounded">{{index $.Tr "article_draft"}}</span>{{end}}
</td>
<td class="px-4 py-3 text-sm text-gray-500">
{{if .PublishedAt}}{{.PublishedAt.Format "2006-01-02 15:04"}}{{else}}—{{end}}
</td>
<td class="px-4 py-3 text-sm text-right whitespace-nowrap">
<a href="/admin/articles/{{.ID}}/edit"
class="text-blue-600 hover:text-blue-800 font-medium mr-3">{{index $.Tr "article_edit"}}</a>
<form class="inline blog-delete-form"
data-url="/api/admin/articles/{{.ID}}"
data-confirm="{{index $.Tr "article_delete_confirm"}}"
onsubmit="return blogDelete(this)">
<button type="submit"
class="text-red-600 hover:text-red-800 font-medium cursor-pointer bg-transparent border-none">{{index $.Tr "article_delete"}}</button>
</form>
</td>
</tr>
{{else}}
<tr>
<td colspan="4" class="px-4 py-12 text-center text-gray-500">{{index .Tr "home_no_posts"}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
</section>
{{template "footer" .}}
{{end}}