feat: 文章新建/编辑页编辑器支持本地图片上传并插入正文

- 两套页面(admin + 普通用户)EasyMDE 的 image 按钮改为“上传图片”:
  选择本地图片 → 走既有附件接口(files 表 type=attachments,新建页
  session_token / 编辑页 article_id)→ 在正文光标处插入 ![](url)
- templates/layouts/base.html:新增共享 window.blogUploadImage 上传助手
- templates/user/my_article_form.html:新建页 session_token 输入框加 id
  (编辑器上传需要读取);补齐原本缺失的上传能力
- i18n:新增 article_image_upload / article_image_not_image(中英)
- 服务端依既有上传策略校验(扩展名/MIME/魔数/大小),客户端限 image/*
This commit is contained in:
dsh
2026-08-28 20:02:46 +08:00
parent 39609ebf03
commit 6216b9af13
4 files changed
+82 -5

No files matched your search

+29 -3
View File
@@ -118,6 +118,32 @@
{{template "footer" .}}
<script>
// 文章附件接口的上下文:新建页用 session_token,编辑页用 article_id。
var ATT = {
articleID: {{ if .FormArticleID }}{{ .FormArticleID }}{{ else }}0{{ end }},
sessionToken: "{{ .SessionToken }}",
uploadURL: "/api/admin/articles/attachments"
};
// 编辑器“上传图片”按钮:选择本地图片 → 上传(files 表,type=attachments)→ 插入正文光标处。
function uploadImageAction(editor) {
var input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = function () {
var f = input.files && input.files[0];
if (!f) return;
blogUploadImage({ url: ATT.uploadURL, file: f, articleID: ATT.articleID, sessionToken: ATT.sessionToken })
.then(function (r) {
if (r.error) { blogShowError('articleError', r.error); return; }
if (!r.is_image) { blogShowError('articleError', '{{index .Tr "article_image_not_image"}}'); return; }
editor.codemirror.replaceSelection('![' + r.filename + '](' + r.url + ')\n');
editor.codemirror.focus();
});
};
input.click();
}
var easyMDE = new EasyMDE({
element: document.getElementById('articleContent'),
autoDownloadFontAwesome: false,
@@ -130,7 +156,7 @@ var easyMDE = new EasyMDE({
toolbar: [
'bold', 'italic', 'heading', '|',
'quote', 'unordered-list', 'ordered-list', '|',
'link', 'image', 'code', 'table', '|',
'link', { name: 'uploadImage', className: 'fa fa-image', title: '{{index .Tr "article_image_upload"}}', action: uploadImageAction }, 'code', 'table', '|',
'preview', 'side-by-side', 'fullscreen', '|',
'guide'
],
@@ -140,8 +166,8 @@ var easyMDE = new EasyMDE({
// ---- Attachments ----
(function () {
var articleID = {{ if .FormArticleID }}{{ .FormArticleID }}{{ else }}0{{ end }};
var sessionToken = "{{ .SessionToken }}";
var articleID = ATT.articleID;
var sessionToken = ATT.sessionToken;
var csrfTokenEl = document.querySelector('meta[name="csrf-token"]');
var csrfToken = csrfTokenEl ? csrfTokenEl.getAttribute('content') : '';
var uploadBtn = document.getElementById('attachmentUploadBtn');