193 lines
8.4 KiB
HTML
Executable File
193 lines
8.4 KiB
HTML
Executable File
{% extends "base.html" %}
|
||
|
||
{% block title %}编辑 Wiki 条目{% endblock %}
|
||
|
||
{% block head %}
|
||
<!-- 引入相关CSS和JS -->
|
||
<link href="{{ url_for('static', filename='libs/quill/quill.snow.css') }}" rel="stylesheet">
|
||
<script src="{{ url_for('static', filename='libs/highlight/highlight.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='libs/highlight/languages/javascript.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='libs/highlight/languages/python.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='libs/highlight/languages/bash.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='libs/highlight/languages/xml.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='libs/quill/quill.min.js') }}"></script>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
{% include 'admin_nav.html' %}
|
||
<div class="admin-wiki-container">
|
||
<h1 class="page-title">编辑 Wiki 条目</h1>
|
||
|
||
<div class="edit-entry-section">
|
||
<h2>编辑条目</h2>
|
||
<form id="editEntryForm" class="entry-form" enctype="multipart/form-data">
|
||
<input type="hidden" id="entry-id" value="{{ entry.id }}">
|
||
<div class="form-group">
|
||
<label for="title">标题</label>
|
||
<input type="text" id="title" name="title" value="{{ entry.title }}" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="version">版本</label>
|
||
<input type="text" id="version" name="version" value="{{ entry.version }}" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="wiki-type">条目类型</label>
|
||
<select id="wiki-type" name="wiki_type" required>
|
||
<option value="version" {% if entry.wiki_type == 'version' %}selected{% endif %}>版本号</option>
|
||
<option value="news" {% if entry.wiki_type == 'news' %}selected{% endif %}>资讯</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="content">内容</label>
|
||
<div id="content-editor" class="editor"></div>
|
||
<input type="hidden" id="content" name="content">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="images">图片上传</label>
|
||
<div class="image-upload-container">
|
||
<div class="image-upload-area" id="imageUploadArea">
|
||
<input type="file" id="images" name="images[]" accept="image/*" multiple class="image-input">
|
||
<div class="upload-placeholder">
|
||
<i class="fas fa-cloud-upload-alt"></i>
|
||
<p>点击或拖拽图片到此处上传</p>
|
||
<span class="upload-hint">支持多张图片上传</span>
|
||
</div>
|
||
</div>
|
||
<div class="image-preview-container" id="imagePreviewContainer">
|
||
{% for image in entry.images %}
|
||
<div class="preview-item" data-path="{{ image }}">
|
||
<img src="{{ url_for('static', filename=image) }}" alt="预览图">
|
||
<span class="preview-remove" onclick="removePreviewItem(this)">×</span>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="btn-primary">更新条目</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Quill 工具栏配置(与添加页面相同)
|
||
const toolbarOptions = [
|
||
// ... 工具栏配置保持不变
|
||
];
|
||
|
||
// 初始化编辑器
|
||
const editor = new Quill('#content-editor', {
|
||
modules: {
|
||
toolbar: {
|
||
container: toolbarOptions,
|
||
handlers: {
|
||
// ... 工具栏处理器保持不变
|
||
}
|
||
},
|
||
syntax: {
|
||
highlight: (text) => hljs.highlightAuto(text).value
|
||
}
|
||
},
|
||
theme: 'snow'
|
||
});
|
||
|
||
// 设置初始内容
|
||
const initialContent = {{ entry.content | tojson | safe }};
|
||
editor.setContents(initialContent);
|
||
|
||
// 表单提交
|
||
document.getElementById('editEntryForm').addEventListener('submit', async function(e) {
|
||
e.preventDefault();
|
||
|
||
try {
|
||
// 获取编辑器内容
|
||
const content = editor.getContents();
|
||
const title = document.getElementById('title').value;
|
||
const version = document.getElementById('version').value;
|
||
const wikiType = document.getElementById('wiki-type').value;
|
||
const entryId = document.getElementById('entry-id').value;
|
||
|
||
// 获取所有预览项的图片文件
|
||
const previewContainer = document.getElementById('imagePreviewContainer');
|
||
const previewItems = previewContainer.getElementsByClassName('preview-item');
|
||
const imagePromises = Array.from(previewItems).map(item => {
|
||
return new Promise((resolve) => {
|
||
const existingPath = item.getAttribute('data-path');
|
||
const file = item._file;
|
||
|
||
if (existingPath && !file) {
|
||
// 如果是已存在的图片,直接返回路径
|
||
resolve({
|
||
name: existingPath.split('/').pop(),
|
||
data: null,
|
||
path: existingPath
|
||
});
|
||
} else if (file) {
|
||
// 如果是新上传的图片
|
||
const reader = new FileReader();
|
||
reader.onload = function(e) {
|
||
const timestamp = Date.now();
|
||
const safeName = file.name.replace(/[^a-zA-Z0-9.]/g, '_');
|
||
const uniqueName = `${timestamp}_${safeName}`;
|
||
|
||
resolve({
|
||
name: uniqueName,
|
||
data: e.target.result.split(',')[1],
|
||
path: 'uploads/wiki/' + uniqueName
|
||
});
|
||
};
|
||
reader.readAsDataURL(file);
|
||
}
|
||
});
|
||
});
|
||
|
||
// 等待所有图片处理完成
|
||
const imageDataUrls = await Promise.all(imagePromises);
|
||
|
||
// 创建 FormData 对象
|
||
const formData = new FormData();
|
||
formData.append('title', title);
|
||
formData.append('version', version);
|
||
formData.append('wiki_type', wikiType);
|
||
formData.append('content', JSON.stringify(content));
|
||
formData.append('entry_id', entryId);
|
||
|
||
// 添加图片数据
|
||
imageDataUrls.forEach((img, index) => {
|
||
formData.append(`images[${index}][name]`, img.name);
|
||
formData.append(`images[${index}][data]`, img.data || '');
|
||
formData.append(`images[${index}][path]`, img.path);
|
||
});
|
||
|
||
const response = await fetch(`/admin/wiki/edit/${entryId}`, {
|
||
method: 'POST',
|
||
body: formData
|
||
// 注意:不要设置 Content-Type,让浏览器自动设置
|
||
});
|
||
|
||
const responseData = await response.json();
|
||
|
||
if (responseData.success) {
|
||
alert('更新成功');
|
||
window.location.href = '/admin/wiki';
|
||
} else {
|
||
alert('更新失败:' + responseData.error);
|
||
}
|
||
} catch (error) {
|
||
console.error('Error:', error);
|
||
alert('更新失败:' + error.message);
|
||
}
|
||
});
|
||
|
||
// 移除预览项的函数
|
||
window.removePreviewItem = function(element) {
|
||
const previewItem = element.closest('.preview-item');
|
||
previewItem.remove();
|
||
};
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
/* 样式与添加页面保持一致 */
|
||
</style>
|
||
{% endblock %} |