2 Commits

Author SHA1 Message Date
7074d84cbc 修复参考来源JSON序列化错误
- 手动将Reference对象转换为JSON字符串
- 避免使用tojson过滤器序列化SQLAlchemy对象
2026-06-04 23:32:16 +08:00
f3ccf25ede 修复文章编辑表单无法提交的问题
- 移除嵌套的附件上传form(HTML不允许表单嵌套)
- 改用div和JavaScript FormData处理附件上传
2026-06-04 23:26:50 +08:00

View File

@@ -350,7 +350,13 @@ function uploadImage(file, isPaste = false) {
}
// 参考来源管理
let references = {% if references %}[{% for ref in references %}{"id": {{ ref.id }}, "title": "{{ ref.title }}", "url": "{{ ref.url or '' }}", "description": "{{ ref.description or '' }}"}{% if not loop.last %}, {% endif %}{% endfor %}]{% else %}[]{% endif %};
let references = {% if references %}[
{% for ref in references %}
{"id": {{ ref.id }}, "title": "{{ ref.title | e }}", "url": "{{ ref.url or '' | e }}", "description": "{{ ref.description or '' | e }}"}
{% if not loop.last %},
{% endif %}
{% endfor %}
]{% else %}[]{% endif %};
function addReference() {
references.push({id: null, title: '', url: '', description: ''});
@@ -387,12 +393,45 @@ editor.addEventListener('input', updatePreview);
// 初始化预览
updatePreview();
// 附件上传函数
{% if article %}
function uploadAttachment() {
const formData = new FormData();
formData.append('article_id', document.getElementById('attachment-article-id').value);
formData.append('file', document.getElementById('attachment-upload-file').files[0]);
formData.append('description', document.getElementById('attachment-desc').value);
fetch('{{ url_for("admin.upload_attachment") }}', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => {
if (data.success) {
location.reload();
}
});
}
function deleteAttachment(id) {
if (confirm('确定删除此附件?')) {
fetch(`/admin/attachment/${id}/delete`, {method: 'POST'})
.then(res => res.json())
.then(data => {
if (data.success) {
location.reload();
}
});
}
}
{% endif %}
</script>
{% endblock %}
{% block content %}
<form method="POST" class="article-form">
<input type="hidden" id="references-json" name="references" value="{{ references | tojson | safe if references else '[]' }}">
<input type="hidden" id="references-json" name="references" value="[{% for ref in references %}{"id": {{ ref.id }}, "title": "{{ ref.title | e }}", "url": "{{ ref.url or '' | e }}", "description": "{{ ref.description or '' | e }}"}{% if not loop.last %}, {% endif %}{% endfor %}]">
<div class="form-row">
<div class="form-group flex-grow">
@@ -515,43 +554,13 @@ updatePreview();
</div>
{% endfor %}
</div>
<form id="attachment-upload-form" enctype="multipart/form-data">
<input type="hidden" name="article_id" value="{{ article.id }}">
<input type="file" name="file" id="attachment-upload">
<input type="text" name="description" placeholder="文件描述(可选)" style="display: inline-block; width: 200px;">
<div class="attachment-upload-area">
<input type="hidden" id="attachment-article-id" value="{{ article.id }}">
<input type="file" id="attachment-upload-file">
<input type="text" id="attachment-desc" placeholder="文件描述(可选)" style="display: inline-block; width: 200px;">
<button type="button" onclick="uploadAttachment()" class="btn btn-sm btn-secondary">上传附件</button>
</form>
</div>
</div>
<script>
function uploadAttachment() {
const form = document.getElementById('attachment-upload-form');
const formData = new FormData(form);
fetch('{{ url_for("admin.upload_attachment") }}', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => {
if (data.success) {
location.reload();
}
});
}
function deleteAttachment(id) {
if (confirm('确定删除此附件?')) {
fetch(`/admin/attachment/${id}/delete`, {method: 'POST'})
.then(res => res.json())
.then(data => {
if (data.success) {
location.reload();
}
});
}
}
</script>
{% endif %}
<div class="form-group">