feat: 新增备份恢复功能 & 改进图片上传体验

- 新增备份管理页面(备份/恢复/下载/删除)
- 新增 backup_service 服务层
- 文章编辑器增加工具栏图片上传按钮
- 优化图片上传交互提示
This commit is contained in:
2026-07-16 16:38:38 +08:00
parent 503a9780b2
commit df2f0860b5
9 changed files with 614 additions and 30 deletions
+1 -1
View File
@@ -17,4 +17,4 @@ def login_required(f):
# 导入子模块以注册路由
from app.routes.admin import auth, dashboard, articles, categories, tags, settings, stats, upload, authors
from app.routes.admin import auth, dashboard, articles, categories, tags, settings, stats, upload, authors, backup
+68
View File
@@ -0,0 +1,68 @@
"""备份管理路由"""
from flask import render_template, request, jsonify, send_file
from app.routes.admin import admin_bp, login_required
from app.services.backup_service import BackupService
@admin_bp.route('/backup')
@login_required
def backup_page():
"""备份管理页面"""
backups = BackupService.list_backups()
stats = {
'total_backups': len(backups),
'total_size': sum(b['size'] for b in backups)
}
return render_template('admin/backup.html', backups=backups, stats=stats)
@admin_bp.route('/backup/create', methods=['POST'])
@login_required
def backup_create():
"""创建备份"""
include_uploads = request.form.get('include_uploads', 'true').lower() == 'true'
result, error = BackupService.create_backup(include_uploads=include_uploads)
if error:
return jsonify({'success': False, 'message': error}), 400
return jsonify({
'success': True,
'backup': {
'filename': result['filename'],
'size': BackupService.format_filesize(result['size']),
'timestamp': result['timestamp']
}
})
@admin_bp.route('/backup/download/<filename>')
@login_required
def backup_download(filename):
"""下载备份文件"""
filepath = BackupService.get_backup_path(filename)
import os
if not os.path.exists(filepath):
return jsonify({'success': False, 'message': '备份文件不存在'}), 404
return send_file(
filepath,
as_attachment=True,
download_name=filename
)
@admin_bp.route('/backup/delete/<filename>', methods=['POST'])
@login_required
def backup_delete(filename):
"""删除备份文件"""
success, error = BackupService.delete_backup(filename)
if not success:
return jsonify({'success': False, 'message': error}), 400
return jsonify({'success': True})