diff --git a/.gitignore b/.gitignore index 42f8356..a893b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ workspace __pycache__ */__pycache__ models -queue_data +projects/queue_data diff --git a/Dockerfile b/Dockerfile index c1bbd82..1a9693b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,6 @@ COPY . . RUN mkdir -p /app/projects RUN mkdir -p /app/public RUN mkdir -p /app/models -RUN mkdir -p /app/queue_data # 下载sentence-transformers模型到models目录 RUN python -c "from sentence_transformers import SentenceTransformer; model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2'); model.save('/app/models/paraphrase-multilingual-MiniLM-L12-v2')" diff --git a/Dockerfile.modelscope b/Dockerfile.modelscope index 22dd439..90caa70 100644 --- a/Dockerfile.modelscope +++ b/Dockerfile.modelscope @@ -26,7 +26,6 @@ RUN pip install --no-cache-dir -i https://mirrors.aliyun.com/pypi/simple/ models RUN mkdir -p /app/projects RUN mkdir -p /app/public RUN mkdir -p /app/models -RUN mkdir -p /app/queue_data # 从modelscope下载sentence-transformers模型到models目录 RUN python -c "from modelscope import snapshot_download; model_dir = snapshot_download('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2'); import shutil; shutil.move(model_dir, '/app/models/paraphrase-multilingual-MiniLM-L12-v2')" diff --git a/README.md b/README.md index 3c66b15..d9b2b34 100644 --- a/README.md +++ b/README.md @@ -571,7 +571,7 @@ qwen-agent/ │ └── tools/ # 工具定义文件 ├── models/ # 模型文件 ├── projects/ # 项目目录 -├── queue_data/ # 队列数据 +│ └── queue_data/ # 队列数据 ├── public/ # 静态文件 ├── embedding/ # 嵌入模型模块 ├── prompt/ # 系统提示词 diff --git a/fastapi_app.py b/fastapi_app.py index beb576c..a35a66a 100644 --- a/fastapi_app.py +++ b/fastapi_app.py @@ -449,6 +449,152 @@ async def cleanup_tasks(older_than_days: int = 7): raise HTTPException(status_code=500, detail=f"清理任务记录失败: {str(e)}") +@app.get("/api/v1/projects") +async def list_all_projects(): + """获取所有项目列表""" + try: + # 获取机器人项目(projects/robot) + robot_dir = "projects/robot" + robot_projects = [] + + if os.path.exists(robot_dir): + for item in os.listdir(robot_dir): + item_path = os.path.join(robot_dir, item) + if os.path.isdir(item_path): + try: + # 读取机器人配置文件 + config_path = os.path.join(item_path, "robot_config.json") + config_data = {} + if os.path.exists(config_path): + with open(config_path, 'r', encoding='utf-8') as f: + config_data = json.load(f) + + # 统计文件数量 + file_count = 0 + if os.path.exists(os.path.join(item_path, "dataset")): + for root, dirs, files in os.walk(os.path.join(item_path, "dataset")): + file_count += len(files) + + robot_projects.append({ + "id": item, + "name": config_data.get("name", item), + "type": "robot", + "status": config_data.get("status", "active"), + "file_count": file_count, + "config": config_data, + "created_at": os.path.getctime(item_path), + "updated_at": os.path.getmtime(item_path) + }) + except Exception as e: + print(f"Error reading robot project {item}: {str(e)}") + robot_projects.append({ + "id": item, + "name": item, + "type": "robot", + "status": "unknown", + "file_count": 0, + "created_at": os.path.getctime(item_path), + "updated_at": os.path.getmtime(item_path) + }) + + # 获取数据集(projects/data) + data_dir = "projects/data" + datasets = [] + + if os.path.exists(data_dir): + for item in os.listdir(data_dir): + item_path = os.path.join(data_dir, item) + if os.path.isdir(item_path): + try: + # 读取处理日志 + log_path = os.path.join(item_path, "processing_log.json") + log_data = {} + if os.path.exists(log_path): + with open(log_path, 'r', encoding='utf-8') as f: + log_data = json.load(f) + + # 统计文件数量 + file_count = 0 + for root, dirs, files in os.walk(item_path): + file_count += len([f for f in files if not f.endswith('.pkl')]) + + # 获取状态 + status = "active" + if log_data.get("status"): + status = log_data["status"] + elif os.path.exists(os.path.join(item_path, "processed")): + status = "completed" + + datasets.append({ + "id": item, + "name": f"数据集 - {item[:8]}...", + "type": "dataset", + "status": status, + "file_count": file_count, + "log_data": log_data, + "created_at": os.path.getctime(item_path), + "updated_at": os.path.getmtime(item_path) + }) + except Exception as e: + print(f"Error reading dataset {item}: {str(e)}") + datasets.append({ + "id": item, + "name": f"数据集 - {item[:8]}...", + "type": "dataset", + "status": "unknown", + "file_count": 0, + "created_at": os.path.getctime(item_path), + "updated_at": os.path.getmtime(item_path) + }) + + all_projects = robot_projects + datasets + + return { + "success": True, + "message": "项目列表获取成功", + "total_projects": len(all_projects), + "robot_projects": robot_projects, + "datasets": datasets, + "projects": all_projects # 保持向后兼容 + } + + except Exception as e: + print(f"Error listing projects: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取项目列表失败: {str(e)}") + + +@app.get("/api/v1/projects/robot") +async def list_robot_projects(): + """获取机器人项目列表""" + try: + response = await list_all_projects() + return { + "success": True, + "message": "机器人项目列表获取成功", + "total_projects": len(response["robot_projects"]), + "projects": response["robot_projects"] + } + except Exception as e: + print(f"Error listing robot projects: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取机器人项目列表失败: {str(e)}") + + +@app.get("/api/v1/projects/datasets") +async def list_datasets(): + """获取数据集列表""" + try: + response = await list_all_projects() + return { + "success": True, + "message": "数据集列表获取成功", + "total_projects": len(response["datasets"]), + "projects": response["datasets"] + } + except Exception as e: + print(f"Error listing datasets: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取数据集列表失败: {str(e)}") + + @app.get("/api/v1/projects/{dataset_id}/tasks") async def get_project_tasks(dataset_id: str): """获取指定项目的所有任务""" @@ -981,63 +1127,6 @@ async def reset_files_processing(dataset_id: str): except Exception as e: raise HTTPException(status_code=500, detail=f"重置文件处理状态失败: {str(e)}") - -def build_directory_tree(path: str, relative_path: str = "") -> dict: - """构建目录树结构""" - import os - - if not os.path.exists(path): - return {} - - tree = { - "name": os.path.basename(path) or "projects", - "path": relative_path, - "type": "directory", - "children": [], - "size": 0, - "modified_time": os.path.getmtime(path) - } - - try: - entries = os.listdir(path) - entries.sort() - - for entry in entries: - entry_path = os.path.join(path, entry) - entry_relative_path = os.path.join(relative_path, entry) if relative_path else entry - - if os.path.isdir(entry_path): - tree["children"].append(build_directory_tree(entry_path, entry_relative_path)) - else: - try: - file_size = os.path.getsize(entry_path) - file_modified = os.path.getmtime(entry_path) - tree["children"].append({ - "name": entry, - "path": entry_relative_path, - "type": "file", - "size": file_size, - "modified_time": file_modified - }) - tree["size"] += file_size - except (OSError, IOError): - tree["children"].append({ - "name": entry, - "path": entry_relative_path, - "type": "file", - "size": 0, - "modified_time": 0 - }) - except (OSError, IOError) as e: - print(f"Error reading directory {path}: {e}") - - return tree - - - - - - # 注册文件管理API路由 app.include_router(file_manager_router) diff --git a/public/admin.html b/public/admin.html new file mode 100644 index 0000000..5b6ade3 --- /dev/null +++ b/public/admin.html @@ -0,0 +1,2227 @@ + + +
+ + +Qwen Agent 系统管理
+管理您的项目文件,支持上传、下载、删除等操作
-