From 970662cf53b23b842fc34d27abce383c52858f2c Mon Sep 17 00:00:00 2001 From: liuwei Date: Wed, 4 Jun 2025 15:36:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=B5=8F=E8=A7=88=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/dashboard/blueprints/file_browser.py | 78 +++++++++++ admin/dashboard/server.py | 2 + admin/dashboard/templates/file_browser.html | 143 ++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 admin/dashboard/blueprints/file_browser.py create mode 100644 admin/dashboard/templates/file_browser.html diff --git a/admin/dashboard/blueprints/file_browser.py b/admin/dashboard/blueprints/file_browser.py new file mode 100644 index 0000000..c218c52 --- /dev/null +++ b/admin/dashboard/blueprints/file_browser.py @@ -0,0 +1,78 @@ +from flask import Blueprint, render_template, jsonify, send_file, request +import os +from loguru import logger + +file_browser_bp = Blueprint('file_browser', __name__) + +@file_browser_bp.route('/file_browser') +def file_browser(): + """文件浏览器页面""" + return render_template('file_browser.html') + +@file_browser_bp.route('/api/list_files') +def list_files(): + """获取指定目录下的文件列表""" + try: + path = request.args.get('path', '') + # 获取项目根目录 + project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + # 构建完整路径 + full_path = os.path.join(project_root, path) + + # 安全检查:确保路径在项目根目录内 + if not os.path.abspath(full_path).startswith(project_root): + return jsonify({"success": False, "message": "访问被拒绝:路径超出项目范围"}) + + if not os.path.exists(full_path): + return jsonify({"success": False, "message": "目录不存在"}) + + items = [] + for item in os.listdir(full_path): + item_path = os.path.join(full_path, item) + is_dir = os.path.isdir(item_path) + items.append({ + "name": item, + "is_dir": is_dir, + "size": os.path.getsize(item_path) if not is_dir else 0, + "modified": os.path.getmtime(item_path) + }) + + return jsonify({ + "success": True, + "data": { + "items": items, + "current_path": path + } + }) + except Exception as e: + logger.error(f"列出文件失败: {e}") + return jsonify({"success": False, "message": str(e)}) + +@file_browser_bp.route('/api/download_file') +def download_file(): + """下载指定文件""" + try: + path = request.args.get('path', '') + # 获取项目根目录 + project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + # 构建完整路径 + full_path = os.path.join(project_root, path) + + # 安全检查:确保路径在项目根目录内 + if not os.path.abspath(full_path).startswith(project_root): + return jsonify({"success": False, "message": "访问被拒绝:路径超出项目范围"}) + + if not os.path.exists(full_path): + return jsonify({"success": False, "message": "文件不存在"}) + + if os.path.isdir(full_path): + return jsonify({"success": False, "message": "不能下载目录"}) + + return send_file( + full_path, + as_attachment=True, + download_name=os.path.basename(full_path) + ) + except Exception as e: + logger.error(f"下载文件失败: {e}") + return jsonify({"success": False, "message": str(e)}) \ No newline at end of file diff --git a/admin/dashboard/server.py b/admin/dashboard/server.py index c767b88..333a588 100644 --- a/admin/dashboard/server.py +++ b/admin/dashboard/server.py @@ -139,6 +139,7 @@ class DashboardServer: from admin.dashboard.blueprints.main import main_bp from admin.dashboard.blueprints.plugin_routes import plugin_routes from admin.dashboard.blueprints.virtual_group import virtual_group_bp + from admin.dashboard.blueprints.file_browser import file_browser_bp # 在app.register_blueprint部分添加 app.register_blueprint(virtual_group_bp, url_prefix='/virtual_group') @@ -150,6 +151,7 @@ class DashboardServer: app.register_blueprint(stats_bp) app.register_blueprint(system_bp) app.register_blueprint(plugin_routes) + app.register_blueprint(file_browser_bp) self.LOG.info("所有蓝图已注册") diff --git a/admin/dashboard/templates/file_browser.html b/admin/dashboard/templates/file_browser.html new file mode 100644 index 0000000..d240831 --- /dev/null +++ b/admin/dashboard/templates/file_browser.html @@ -0,0 +1,143 @@ +{% extends "base.html" %} + +{% block title %}文件浏览器{% endblock %} + +{% block content %} +
+
+
+
+
+

文件浏览器

+
+
+ +
+ +
+
+
+
+
+
+ + + + + + + + + + + + + +
名称类型大小修改时间操作
+
+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} \ No newline at end of file