# km_cloud **Repository Path**: battlerabbit/km_cloud ## Basic Information - **Project Name**: km_cloud - **Description**: 生物信息云平台前后端代码 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-27 - **Last Updated**: 2026-10-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 生物信息云平台 (Bioinformatics Cloud Platform) [![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) [![Flask](https://img.shields.io/badge/Flask-2.0+-green.svg)](https://flask.palletsprojects.com/) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ## 目录 - [项目简介](#项目简介) - [软件概述](#软件概述) - [技术架构](#技术架构) - [功能模块](#功能模块) - [数据库设计](#数据库设计) - [API接口文档](#api接口文档) - [安全设计](#安全设计) - [性能优化](#性能优化) - [系统要求](#系统要求) - [快速开始](#快速开始) - [部署指南](#部署指南) - [配置说明](#配置说明) - [使用指南](#使用指南) - [运维监控](#运维监控) - [开发文档](#开发文档) - [常见问题](#常见问题) - [更新日志](#更新日志) - [贡献指南](#贡献指南) - [联系方式](#联系方式) --- ## 项目简介 生物信息云平台是一个面向科研人员的**一站式生物信息分析云平台**,采用微服务架构,集成了数据管理、工具运行、任务调度和结果可视化等完整功能链路。用户可以通过浏览器上传数据、配置参数、运行生信工具、监控任务进度并下载分析结果,无需复杂的本地环境配置。 **核心特性:** - 🚀 **开箱即用**: Docker容器化部署,无需手动配置复杂依赖 - 🔐 **用户隔离**: 多用户支持,数据隔离与权限控制 - 📁 **智能文件管理**: 集成FileBrowser,支持拖拽上传、在线预览 - 🧬 **工具扩展**: JSON配置化工具管理,轻松添加新的生信工具 - 📊 **实时监控**: 任务状态实时追踪,资源使用情况可视化 - 🔄 **异步任务**: 基于Celery的分布式任务队列,支持大规模并发 --- ## 软件概述 ### 软件定位 本平台旨在解决生物信息学研究中工具部署复杂、环境配置繁琐、任务管理困难等问题,为科研团队提供统一的在线分析平台。 ### 软件目标 1. **降低使用门槛**: 无需Linux和命令行知识,图形化界面完成所有操作 2. **提高分析效率**: 批量任务处理,结果自动归档,重复工作自动化 3. **保障数据安全**: 用户数据隔离,完整的备份与恢复机制 4. **支持团队协作**: 项目共享,结果可视化,便于团队交流 ### 应用场景 - 基因组数据分析 - 转录组数据处理 - 蛋白质组学分析 - 宏基因组学研究 - 个性化医疗数据分析 - 教学与培训演示 --- ## 技术架构 ### 系统架构图 ``` ┌─────────────────────────────────────────────────────────────┐ │ 用户浏览器 │ │ (Tailwind CSS + JS) │ └────────────────────────────┬────────────────────────────────┘ │ HTTPS ▼ ┌─────────────────────────────────────────────────────────────┐ │ Nginx 反向代理 │ │ (SSL终止 + 负载均衡) │ └───┬───────────────┬───────────────┬───────────────┬──────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────┐ ┌─────────────┐ ┌─────────┐ ┌─────────────┐ │Flask │ │ FileBrowser │ │ Celery │ │ Flower │ │ Web │ │ 文件管理 │ │ Worker │ │ 任务监控 │ └───┬────┘ └─────────────┘ └────┬────┘ └─────────────┘ │ │ ▼ ▼ ┌──────────────────┐ ┌──────────────────────┐ │ PostgreSQL │ │ Redis │ │ (用户/任务数据) │ │ (缓存/消息队列) │ └──────────────────┘ └──────────────────────┘ │ ▼ ┌─────────────────┐ │ ClickHouse │ │ (时序/日志数据) │ └─────────────────┘ ``` ### 技术栈 #### 后端技术 | 技术 | 版本 | 用途 | |------|------|------| | Python | 3.8+ | 开发语言 | | Flask | 2.0+ | Web框架 | | PostgreSQL | 13+ | 关系型数据库 | | ClickHouse | 21+ | 时序数据库 | | Redis | 6.0+ | 缓存与消息队列 | | Celery | 5.0+ | 分布式任务队列 | | Flower | 1.0+ | 任务监控 | | FileBrowser | 2.0+ | 文件管理服务 | | Psycopg2 | 2.8+ | PostgreSQL驱动 | | SQLAlchemy | 1.4+ | ORM框架 | #### 前端技术 | 技术 | 版本 | 用途 | |------|------|------| | Tailwind CSS | 3.0+ | UI样式框架 | | Font Awesome | 6.0+ | 图标库 | | Chart.js | 3.0+ | 数据可视化 | | Alpine.js | 3.0+ | 前端交互框架 | #### DevOps技术 | 技术 | 版本 | 用途 | |------|------|------| | Docker | 20.10+ | 容器化 | | Docker Compose | 1.29+ | 容器编排 | | Nginx | 1.20+ | 反向代理 | | Gunicorn | 20.0+ | WSGI服务器 | ### 目录结构 ``` km_cloud/ ├── app.py # Flask应用入口 ├── app_config.py # 应用配置模块 ├── pyproject.toml # 项目依赖配置 ├── environment.yml # Conda环境配置 ├── Dockerfile # Docker镜像构建文件 ├── docker-compose.yaml # Docker编排文件 │ ├── config/ # 配置文件目录 │ ├── nginx.conf # Nginx配置 │ └── postgres.conf # PostgreSQL配置 │ ├── init-scripts/ # 数据库初始化脚本 │ ├── 001_init_users.sql │ ├── 002_init_tasks.sql │ └── 003_init_logs.sql │ ├── models/ # 数据模型 │ ├── user.py # 用户模型 │ └── task.py # 任务模型 │ ├── routes/ # 路由模块 │ ├── auth.py # 认证路由 │ ├── files.py # 文件管理路由 │ ├── filebrowser.py # FileBrowser代理 │ ├── upload.py # 上传路由 │ ├── tasks.py # 任务路由 │ ├── tools.py # 工具路由 │ └── projects.py # 项目路由 │ ├── services/ # 业务服务层 │ ├── task_service.py # 任务服务 │ └── file_service.py # 文件服务 │ ├── utils/ # 工具函数 │ ├── db.py # 数据库工具 │ ├── auth.py # 认证工具 │ └── validator.py # 数据验证 │ ├── templates/ # HTML模板 │ ├── index.html # 首页 │ ├── login.html # 登录页 │ ├── register.html # 注册页 │ ├── projects.html # 项目管理页 │ ├── tools.html # 工具列表页 │ └── profile.html # 个人中心页 │ ├── static/ # 静态资源 │ ├── css/ # 样式文件 │ ├── js/ # JavaScript文件 │ └── fonts/ # 字体文件 │ ├── tool_configs/ # 工具配置文件 │ ├── blast.yml # BLAST工具配置 │ ├── bowtie2.yml # Bowtie2工具配置 │ └── samtools.yml # Samtools工具配置 │ ├── biopipe/ # 生信工具脚本 │ ├── blast/ # BLAST工具 │ ├── bowtie2/ # Bowtie2工具 │ └── samtools/ # Samtools工具 │ ├── biopipe_cloud/ # 云端工具适配 │ ├── adapters/ # 工具适配器 │ └── wrappers/ # 工具封装 │ ├── km_cloud_tools/ # Go语言工具 │ └── *.go # 各类工具实现 │ ├── app_data/ # 应用数据目录 │ ├── bio_data/ # 用户生物数据 │ │ └── {user_id}/ # 用户隔离目录 │ └── uploads/ # 上传临时文件 │ ├── cloud_report/ # 云报告模块 └── test_data/ # 测试数据 ``` --- ## 功能模块 ### 1. 用户认证模块 (Authentication) **功能描述:** - 用户注册与登录 - 密码加密存储(bcrypt) - 会话管理(Flask-Session) - 密码找回与重置 - 邮箱验证 - 用户权限管理(普通用户/管理员) **核心接口:** - `POST /api/register` - 用户注册 - `POST /api/login` - 用户登录 - `POST /api/logout` - 用户登出 - `GET /api/profile` - 获取个人信息 - `PUT /api/profile` - 更新个人信息 - `POST /api/change-password` - 修改密码 **实现细节:** ```python # 密码加密 from werkzeug.security import generate_password_hash, check_password_hash hashed_password = generate_password_hash(password) check_password_hash(hashed_password, input_password) ``` ### 2. 文件管理模块 (File Management) **功能描述:** - 文件上传(支持拖拽、批量上传) - 文件下载与在线预览 - 文件重命名、移动、删除 - 文件夹管理(创建、重命名、删除) - 文件搜索与过滤 - 文件权限控制 - 存储空间配额管理 **集成FileBrowser:** - 使用FileBrowser --noauth模式 - 通过Flask代理实现用户路径隔离 - 用户数据路径:`/app_data/bio_data/{user_id}/` **核心接口:** - `POST /api/upload` - 上传文件 - `GET /api/files` - 获取文件列表 - `DELETE /api/files/{path}` - 删除文件 - `POST /api/files/rename` - 重命名文件 - `GET /api/upload-quota` - 获取存储配额 **存储配额管理:** - 默认配额:10GB - 管理员可调整用户配额 - 超配额提示与限制 ### 3. 任务调度模块 (Task Scheduling) **功能描述:** - 任务提交与排队 - 任务状态实时追踪 - 任务优先级管理 - 任务取消与重试 - 任务日志查看 - 任务结果归档 - 批量任务提交 **任务状态流转:** ``` PENDING → RUNNING → SUCCESS/FALIED ↓ CANCELLED ``` **核心接口:** - `POST /api/tasks` - 提交任务 - `GET /api/tasks` - 获取任务列表 - `GET /api/tasks/{task_id}` - 获取任务详情 - `DELETE /api/tasks/{task_id}` - 取消任务 - `GET /api/tasks/{task_id}/logs` - 获取任务日志 - `GET /api/tasks/{task_id}/result` - 获取任务结果 **Celery任务配置:** ```python # tasks.py from celery import Celery app = Celery('biopipe') app.conf.update( broker_url='redis://redis:6379/0', result_backend='redis://redis:6379/0', task_serializer='json', accept_content=['json'], result_serializer='json', timezone='Asia/Shanghai', enable_utc=True, task_track_started=True, task_time_limit=3600, # 1小时超时 ) ``` ### 4. 工具管理模块 (Tool Management) **功能描述:** - 工具列表展示 - 工具参数配置 - 工具版本管理 - 工具搜索与分类 - 自定义工具添加 - 工具执行历史 **工具配置格式:** ```yaml # tool_configs/blast.yml id: blast name: BLAST version: 2.13.0 description: Basic Local Alignment Search Tool category: sequence_alignment parameters: - name: query_file label: Query File type: file required: true description: Input sequence file - name: database label: Database type: select required: true options: - nt - nr - refseq_rna description: BLAST database - name: evalue label: E-value type: number required: false default: 0.001 description: Expectation value threshold ``` **核心接口:** - `GET /api/tools` - 获取工具列表 - `GET /api/tools/{tool_id}` - 获取工具详情 - `POST /api/tools/{tool_id}/run` - 运行工具 - `GET /api/tools/{tool_id}/history` - 获取工具执行历史 ### 5. 项目管理模块 (Project Management) **功能描述:** - 项目创建与编辑 - 项目成员管理 - 项目文件组织 - 项目任务统计 - 项目结果分享 **核心接口:** - `GET /api/projects` - 获取项目列表 - `POST /api/projects` - 创建项目 - `PUT /api/projects/{project_id}` - 更新项目 - `DELETE /api/projects/{project_id}` - 删除项目 - `GET /api/projects/{project_id}/tasks` - 获取项目任务 ### 6. 监控告警模块 (Monitoring & Alerting) **功能描述:** - 系统资源监控(CPU、内存、磁盘) - 任务队列监控 - 数据库性能监控 - 异常告警通知 - 日志集中管理 **Flower监控界面:** - 实时任务状态 - Worker状态 - 任务执行时间统计 - 任务成功率 **核心接口:** - `GET /api/health` - 健康检查 - `GET /api/stats` - 系统统计 - `GET /api/queue/status` - 队列状态 --- ## 数据库设计 ### PostgreSQL 数据库设计 #### 用户表 (users) | 字段 | 类型 | 说明 | 约束 | |------|------|------|------| | id | INTEGER | 用户ID | PRIMARY KEY, AUTO_INCREMENT | | username | VARCHAR(50) | 用户名 | UNIQUE, NOT NULL | | email | VARCHAR(100) | 邮箱 | UNIQUE, NOT NULL | | password_hash | VARCHAR(255) | 密码哈希 | NOT NULL | | full_name | VARCHAR(100) | 全名 | | | created_at | TIMESTAMP | 创建时间 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新时间 | DEFAULT CURRENT_TIMESTAMP | | is_active | BOOLEAN | 是否激活 | DEFAULT TRUE | | is_admin | BOOLEAN | 是否管理员 | DEFAULT FALSE | | quota | BIGINT | 存储配额(字节) | DEFAULT 10737418240 | | used_quota | BIGINT | 已用空间(字节) | DEFAULT 0 | **SQL定义:** ```sql CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_active BOOLEAN DEFAULT TRUE, is_admin BOOLEAN DEFAULT FALSE, quota BIGINT DEFAULT 10737418240, used_quota BIGINT DEFAULT 0 ); CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email ON users(email); ``` #### 任务表 (tasks) | 字段 | 类型 | 说明 | 约束 | |------|------|------|------| | id | INTEGER | 任务ID | PRIMARY KEY, AUTO_INCREMENT | | user_id | INTEGER | 用户ID | FOREIGN KEY → users.id | | tool_id | VARCHAR(50) | 工具ID | | | name | VARCHAR(200) | 任务名称 | NOT NULL | | status | VARCHAR(20) | 任务状态 | NOT NULL | | parameters | JSONB | 任务参数 | | | result_path | VARCHAR(500) | 结果路径 | | | error_message | TEXT | 错误信息 | | | created_at | TIMESTAMP | 创建时间 | DEFAULT CURRENT_TIMESTAMP | | started_at | TIMESTAMP | 开始时间 | | | completed_at | TIMESTAMP | 完成时间 | | | celery_task_id | VARCHAR(255) | Celery任务ID | UNIQUE | **SQL定义:** ```sql CREATE TABLE tasks ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, tool_id VARCHAR(50), name VARCHAR(200) NOT NULL, status VARCHAR(20) NOT NULL, parameters JSONB, result_path VARCHAR(500), error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, started_at TIMESTAMP, completed_at TIMESTAMP, celery_task_id VARCHAR(255) UNIQUE ); CREATE INDEX idx_tasks_user_id ON tasks(user_id); CREATE INDEX idx_tasks_status ON tasks(status); CREATE INDEX idx_tasks_created_at ON tasks(created_at); ``` #### 项目表 (projects) | 字段 | 类型 | 说明 | 约束 | |------|------|------|------| | id | INTEGER | 项目ID | PRIMARY KEY, AUTO_INCREMENT | | user_id | INTEGER | 创建用户ID | FOREIGN KEY → users.id | | name | VARCHAR(200) | 项目名称 | NOT NULL | | description | TEXT | 项目描述 | | | created_at | TIMESTAMP | 创建时间 | DEFAULT CURRENT_TIMESTAMP | | updated_at | TIMESTAMP | 更新时间 | DEFAULT CURRENT_TIMESTAMP | **SQL定义:** ```sql CREATE TABLE projects ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(200) NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_projects_user_id ON projects(user_id); ``` #### 工具执行历史表 (tool_history) | 字段 | 类型 | 说明 | 约束 | |------|------|------|------| | id | INTEGER | 记录ID | PRIMARY KEY, AUTO_INCREMENT | | user_id | INTEGER | 用户ID | FOREIGN KEY → users.id | | tool_id | VARCHAR(50) | 工具ID | | | task_id | INTEGER | 任务ID | FOREIGN KEY → tasks.id | | executed_at | TIMESTAMP | 执行时间 | DEFAULT CURRENT_TIMESTAMP | | parameters | JSONB | 参数 | | ### ClickHouse 时序数据设计 #### 任务执行日志表 (task_logs) ```sql CREATE TABLE task_logs ( task_id UInt64, timestamp DateTime, level String, message String, source String ) ENGINE = MergeTree() PARTITION BY toYYYYMM(timestamp) ORDER BY (task_id, timestamp); ``` #### 系统指标表 (system_metrics) ```sql CREATE TABLE system_metrics ( timestamp DateTime, cpu_usage Float64, memory_usage Float64, disk_usage Float64, network_in UInt64, network_out UInt64, active_tasks UInt32 ) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(timestamp) ORDER BY timestamp; ``` ### Redis 数据结构 | Key | 类型 | 说明 | TTL | |-----|------|------|-----| | `session:{session_id}` | Hash | 用户会话 | 7天 | | `task:{task_id}` | Hash | 任务缓存 | 24小时 | | `task:queue:pending` | List | 待处理任务队列 | 永久 | | `task:queue:running` | Set | 运行中任务 | 永久 | | `user:{user_id}:files` | Set | 用户文件列表 | 永久 | | `lock:{resource}` | String | 分布式锁 | 1小时 | --- ## API接口文档 ### 认证接口 #### POST /api/register 用户注册 **请求体:** ```json { "username": "user123", "email": "user@example.com", "password": "securePassword123", "full_name": "张三" } ``` **响应:** ```json { "success": true, "message": "注册成功", "data": { "user_id": 1, "username": "user123", "email": "user@example.com" } } ``` #### POST /api/login 用户登录 **请求体:** ```json { "username": "user123", "password": "securePassword123" } ``` **响应:** ```json { "success": true, "message": "登录成功", "data": { "user_id": 1, "username": "user123", "is_admin": false } } ``` ### 文件接口 #### POST /api/upload 上传文件 **请求:** - Method: `POST` - Content-Type: `multipart/form-data` - Body: `file` (文件), `path` (可选,目标路径) **响应:** ```json { "success": true, "message": "上传成功", "data": { "filename": "sample.fasta", "path": "/uploads/sample.fasta", "size": 1024000 } } ``` #### GET /api/upload-quota 获取存储配额 **响应:** ```json { "success": true, "data": { "total": 10737418240, "used": 5368709120, "remaining": 5368709120, "percentage": 50 } } ``` ### 任务接口 #### POST /api/tasks 提交任务 **请求体:** ```json { "tool_id": "blast", "name": "BLAST分析任务", "parameters": { "query_file": "/uploads/query.fasta", "database": "nr", "evalue": 0.001 } } ``` **响应:** ```json { "success": true, "message": "任务已提交", "data": { "task_id": 123, "status": "PENDING", "created_at": "2024-01-05T10:00:00Z" } } ``` #### GET /api/tasks 获取任务列表 **查询参数:** - `page`: 页码(默认1) - `per_page`: 每页数量(默认20) - `status`: 状态过滤 **响应:** ```json { "success": true, "data": { "total": 100, "page": 1, "per_page": 20, "tasks": [ { "id": 123, "name": "BLAST分析任务", "tool_id": "blast", "status": "RUNNING", "created_at": "2024-01-05T10:00:00Z" } ] } } ``` ### 工具接口 #### GET /api/tools 获取工具列表 **响应:** ```json { "success": true, "data": [ { "id": "blast", "name": "BLAST", "version": "2.13.0", "description": "Basic Local Alignment Search Tool", "category": "sequence_alignment" }, { "id": "bowtie2", "name": "Bowtie2", "version": "2.5.1", "description": "Ultrafast and memory-efficient aligner", "category": "sequence_alignment" } ] } ``` --- ## 安全设计 ### 1. 认证与授权 **密码安全:** - 使用bcrypt进行密码哈希(成本因子12) - 强制密码复杂度要求(至少8位,包含大小写字母和数字) - 密码重置令牌有效期1小时 **会话管理:** - 基于Flask-Session的服务端会话 - 会话有效期7天 - 敏感操作二次验证 - 登出时销毁会话 ### 2. 数据隔离 **用户数据隔离:** - 每个用户拥有独立的数据目录:`/app_data/bio_data/{user_id}/` - 文件系统权限控制 - 数据库查询强制添加user_id过滤 **示例代码:** ```python @login_required def get_user_files(): user_id = session.get('user_id') user_path = os.path.join(DATA_ROOT, str(user_id)) # 只返回该用户的文件 files = list_files(user_path) return jsonify(files) ``` ### 3. 输入验证 **参数验证:** - 所有API输入参数进行类型和范围验证 - SQL注入防护(使用参数化查询) - XSS防护(模板自动转义) **示例:** ```python from werkzeug.security import safe_str_cmp def validate_input(data): if not isinstance(data.get('username'), str): raise ValueError('用户名必须是字符串') if len(data['username']) > 50: raise ValueError('用户名长度不能超过50') # 更多验证... ``` ### 4. HTTPS与传输安全 - 生产环境强制HTTPS - HTTP自动重定向到HTTPS - 使用TLS 1.2+加密 - HSTS头部配置 ### 5. 安全头部 ```nginx add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Content-Security-Policy "default-src 'self'"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; ``` --- ## 性能优化 ### 1. 数据库优化 **索引优化:** ```sql -- 用户查询索引 CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_username ON users(username); -- 任务查询索引 CREATE INDEX idx_tasks_user_id ON tasks(user_id); CREATE INDEX idx_tasks_status ON tasks(status); CREATE INDEX idx_tasks_created_at ON tasks(created_at DESC); -- 复合索引 CREATE INDEX idx_tasks_user_status ON tasks(user_id, status); ``` **查询优化:** - 使用分页查询避免数据量过大 - 使用SELECT只查询需要的字段 - 避免N+1查询问题,使用JOIN ### 2. 缓存策略 **Redis缓存:** - 用户会话缓存(7天TTL) - 工具配置缓存(1小时TTL) - 任务状态缓存(5分钟TTL) - 文件列表缓存(10分钟TTL) **示例代码:** ```python from flask_caching import Cache cache = Cache(config={'CACHE_TYPE': 'redis'}) @cache.cached(timeout=300, key_prefix='tools') def get_tools(): return Tool.query.all() ``` ### 3. 异步处理 **Celery任务队列:** - 长时间任务异步执行 - 任务优先级队列 - 任务超时控制 - 自动重试机制 **配置:** ```python app.conf.task_acks_late = True app.conf.worker_prefetch_multiplier = 1 app.conf.task_time_limit = 3600 app.conf.task_soft_time_limit = 3300 app.conf.task_reject_on_worker_lost = True ``` ### 4. 静态资源优化 - 启用Gzip压缩 - 静态资源CDN加速 - 图片懒加载 - 资源合并与压缩 ### 5. 数据库连接池 ```python from sqlalchemy import create_engine from sqlalchemy.pool import QueuePool engine = create_engine( DATABASE_URL, poolclass=QueuePool, pool_size=10, max_overflow=20, pool_timeout=30, pool_recycle=3600 ) ``` --- ## 系统要求 ### 最低配置 | 资源 | 要求 | |------|------| | CPU | 2核心 | | 内存 | 4GB | | 硬盘 | 50GB SSD | | 操作系统 | Linux (Ubuntu 20.04+, CentOS 7+) | | Docker | 20.10+ | | Docker Compose | 1.29+ | ### 推荐配置 | 资源 | 要求 | |------|------| | CPU | 4核心+ | | 内存 | 8GB+ | | 硬盘 | 200GB+ SSD | | 网络 | 千兆网络 | ### 软件依赖 - Python 3.8+ - PostgreSQL 13+ - Redis 6.0+ - ClickHouse 21+ - Nginx 1.20+ --- ## 快速开始 ### 1. 克隆项目 ```bash git clone https://github.com/yourusername/km_cloud.git cd km_cloud ``` ### 2. 环境准备 确保已安装Docker和Docker Compose: ```bash docker --version docker-compose --version ``` ### 3. 配置环境变量 创建 `.env` 文件: ```bash cp .env.example .env ``` 编辑 `.env` 文件,配置以下变量: ```bash # 数据库配置 DB_HOST=postgres DB_NAME=km_cloud_db DB_USER=postgres DB_PASSWORD=your_secure_password DB_PORT=5432 # Flask配置 SECRET_KEY=your_secret_key_here_change_in_production FLASK_ENV=production FLASK_DEBUG=0 # Redis配置 REDIS_HOST=redis REDIS_PORT=6379 REDIS_DB=0 # ClickHouse配置 CLICKHOUSE_HOST=clickhouse CLICKHOUSE_PORT=9000 CLICKHOUSE_USER=default CLICKHOUSE_PASSWORD= # 邮件配置(可选) SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your_email@gmail.com SMTP_PASSWORD=your_app_password # 文件存储配置 DATA_ROOT=/app_data/bio_data UPLOAD_LIMIT=1000000000 # 1GB # 管理员配置 ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=admin_secure_password # FileBrowser配置 FILEBROWSER_USERNAME=admin FILEBROWSER_PASSWORD=change_me ``` ### 4. 启动服务 ```bash # 构建并启动所有服务 docker-compose up -d # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs -f app ``` ### 5. 初始化数据库 ```bash # 执行初始化脚本 docker-compose exec -T postgres psql -U postgres -d km_cloud_db < init-scripts/001_init_users.sql docker-compose exec -T postgres psql -U postgres -d km_cloud_db < init-scripts/002_init_tasks.sql docker-compose exec -T postgres psql -U postgres -d km_cloud_db < init-scripts/003_init_logs.sql ``` ### 6. 访问应用 打开浏览器访问: - 应用首页:`http://localhost:8080` - Flower监控:`http://localhost:5555` - FileBrowser:`http://localhost:8081` ### 7. 创建管理员账户 ```bash # 进入应用容器 docker-compose exec app python # 在Python交互环境中执行 from werkzeug.security import generate_password_hash from models import db, User admin = User( username='admin', email='admin@example.com', password_hash=generate_password_hash('admin123'), is_admin=True ) db.session.add(admin) db.session.commit() ``` --- ## 部署指南 ### Docker部署 #### 1. 单机部署 ```bash # 使用docker-compose一键部署 docker-compose up -d # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs -f ``` #### 2. 生产环境部署 **使用Gunicorn + Nginx:** `docker-compose.prod.yml`: ```yaml version: '3.8' services: app: build: . command: gunicorn -w 4 -b 0.0.0.0:5000 app:app environment: - FLASK_ENV=production depends_on: - postgres - redis volumes: - ./app_data:/app_data restart: unless-stopped nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./config/nginx.conf:/etc/nginx/nginx.conf - ./certs:/etc/nginx/certs depends_on: - app restart: unless-stopped ``` 启动生产环境: ```bash docker-compose -f docker-compose.prod.yml up -d ``` #### 3. 负载均衡部署 使用Nginx进行负载均衡: ```nginx upstream app_servers { least_conn; server app1:5000 weight=1 max_fails=3 fail_timeout=30s; server app2:5000 weight=1 max_fails=3 fail_timeout=30s; server app3:5000 weight=1 max_fails=3 fail_timeout=30s; } server { listen 80; server_name yourdomain.com; location / { proxy_pass http://app_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` ### Kubernetes部署 #### 1. 创建命名空间 ```bash kubectl create namespace km-cloud ``` #### 2. 创建配置映射 ```yaml # configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: km-cloud-config namespace: km-cloud data: DB_HOST: "postgres-service" DB_NAME: "km_cloud_db" REDIS_HOST: "redis-service" FLASK_ENV: "production" --- apiVersion: v1 kind: Secret metadata: name: km-cloud-secret namespace: km-cloud type: Opaque stringData: DB_PASSWORD: "your_password" SECRET_KEY: "your_secret_key" ``` ```bash kubectl apply -f configmap.yaml ``` #### 3. 部署应用 ```yaml # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: km-cloud-app namespace: km-cloud spec: replicas: 3 selector: matchLabels: app: km-cloud template: metadata: labels: app: km-cloud spec: containers: - name: app image: your-registry/km-cloud:latest ports: - containerPort: 5000 envFrom: - configMapRef: name: km-cloud-config - secretRef: name: km-cloud-secret resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "1Gi" cpu: "1000m" ``` #### 4. 创建服务 ```yaml # service.yaml apiVersion: v1 kind: Service metadata: name: km-cloud-service namespace: km-cloud spec: selector: app: km-cloud ports: - protocol: TCP port: 80 targetPort: 5000 type: LoadBalancer ``` ```bash kubectl apply -f deployment.yaml kubectl apply -f service.yaml ``` --- ## 配置说明 ### 应用配置 (app_config.py) ```python import os from pathlib import Path class Config: """基础配置类""" # Flask配置 SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key') DEBUG = os.environ.get('FLASK_DEBUG', '0') == '1' # 数据库配置 DB_HOST = os.environ.get('DB_HOST', 'localhost') DB_PORT = os.environ.get('DB_PORT', '5432') DB_NAME = os.environ.get('DB_NAME', 'km_cloud_db') DB_USER = os.environ.get('DB_USER', 'postgres') DB_PASSWORD = os.environ.get('DB_PASSWORD', 'password') @property def DATABASE_URL(self): return f"postgresql://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}" # Redis配置 REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost') REDIS_PORT = int(os.environ.get('REDIS_PORT', '6379')) REDIS_DB = int(os.environ.get('REDIS_DB', '0')) # ClickHouse配置 CLICKHOUSE_HOST = os.environ.get('CLICKHOUSE_HOST', 'localhost') CLICKHOUSE_PORT = int(os.environ.get('CLICKHOUSE_PORT', '9000')) # Celery配置 CELERY_BROKER_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" CELERY_RESULT_BACKEND = f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" # 文件存储配置 DATA_ROOT = Path(os.environ.get('DATA_ROOT', './app_data/bio_data')) UPLOAD_LIMIT = int(os.environ.get('UPLOAD_LIMIT', '1000000000')) # 1GB ALLOWED_EXTENSIONS = {'fasta', 'fa', 'fastq', 'fq', 'bam', 'sam', 'vcf', 'txt', 'csv'} # 工具配置目录 TOOLS_CONFIG_DIR = Path(__file__).parent / 'tool_configs' # 邮件配置 SMTP_HOST = os.environ.get('SMTP_HOST', 'smtp.gmail.com') SMTP_PORT = int(os.environ.get('SMTP_PORT', '587')) SMTP_USER = os.environ.get('SMTP_USER') SMTP_PASSWORD = os.environ.get('SMTP_PASSWORD') # 安全配置 MAX_CONTENT_LENGTH = 100 * 1024 * 1024 # 100MB PERMANENT_SESSION_LIFETIME = 60 * 60 * 24 * 7 # 7天 # 分页配置 ITEMS_PER_PAGE = 20 ``` ### Nginx配置 (config/nginx.conf) ```nginx user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; # 基础配置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; client_max_body_size 100M; # Gzip压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss; # 安全头部 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # 上游服务器 upstream app_backend { least_conn; server app:5000 max_fails=3 fail_timeout=30s; } server { listen 80; server_name localhost; # 静态文件 location /static/ { alias /app/static/; expires 30d; add_header Cache-Control "public, immutable"; } # API请求 location /api/ { proxy_pass http://app_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 其他请求 location / { proxy_pass http://app_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } ``` --- ## 使用指南 ### 1. 用户注册与登录 #### 注册新账户 1. 访问 `http://your-domain.com/register` 2. 填写用户名、邮箱、密码等信息 3. 点击"注册"按钮 4. 系统发送验证邮件(可选) 5. 验证邮箱后账户激活 #### 登录系统 1. 访问 `http://your-domain.com/login` 2. 输入用户名/邮箱和密码 3. 点击"登录"按钮 4. 登录成功后跳转到首页 ### 2. 文件管理 #### 上传文件 1. 进入"项目管理"页面 2. 点击"上传文件"按钮 3. 选择要上传的文件或拖拽文件到上传区域 4. 等待上传完成 5. 文件自动保存到用户目录 #### 管理文件 - **浏览文件**: 在FileBrowser中浏览您的文件 - **下载文件**: 点击文件即可下载 - **删除文件**: 选中文件后点击"删除"按钮 - **重命名文件**: 选中文件后点击"重命名" - **创建文件夹**: 点击"新建文件夹"按钮 ### 3. 运行分析工具 #### 选择工具 1. 进入"工具中心"页面 2. 浏览工具列表或搜索工具 3. 点击工具卡片查看详细信息 #### 配置参数 1. 点击"运行工具"按钮 2. 根据工具要求选择或输入参数 3. 点击"提交任务"按钮 #### 监控任务 1. 进入"任务中心"页面 2. 查看任务列表和状态 3. 点击任务查看详细信息 4. 点击"查看日志"查看任务执行日志 5. 任务完成后下载结果文件 ### 4. 项目管理 #### 创建项目 1. 进入"项目管理"页面 2. 点击"新建项目"按钮 3. 输入项目名称和描述 4. 点击"创建"按钮 #### 管理项目 - **查看项目**: 点击项目卡片查看项目详情 - **编辑项目**: 点击"编辑"修改项目信息 - **删除项目**: 点击"删除"移除项目 - **查看项目任务**: 在项目页面查看相关任务 ### 5. 个人中心 #### 修改个人信息 1. 点击右上角用户名 2. 选择"个人中心" 3. 修改用户信息 4. 点击"保存"按钮 #### 修改密码 1. 在个人中心页面 2. 输入当前密码 3. 输入新密码并确认 4. 点击"修改密码"按钮 #### 查看存储使用情况 1. 在个人中心页面 2. 查看"存储使用情况"卡片 3. 显示已用空间和剩余空间 --- ## 运维监控 ### 1. 健康检查 ```bash # 检查应用健康状态 curl http://localhost:8080/api/health # 检查数据库连接 docker-compose exec postgres pg_isready # 检查Redis连接 docker-compose exec redis redis-cli ping # 检查Celery Worker curl http://localhost:5555 ``` ### 2. 日志查看 ```bash # 查看应用日志 docker-compose logs -f app # 查看Nginx日志 docker-compose logs -f nginx # 查看Celery日志 docker-compose logs -f celery # 查看PostgreSQL日志 docker-compose logs -f postgres # 查看特定时间段的日志 docker-compose logs --since 2024-01-01T00:00:00 app ``` ### 3. 性能监控 #### Flower监控 访问 `http://localhost:5555` 查看: - Worker状态 - 任务执行情况 - 任务队列长度 - 任务执行时间统计 #### 系统资源监控 ```bash # 查看容器资源使用 docker stats # 查看磁盘使用 df -h # 查看内存使用 free -h # 查看CPU使用 top ``` ### 4. 数据库维护 #### PostgreSQL备份 ```bash # 备份数据库 docker-compose exec postgres pg_dump -U postgres km_cloud_db > backup.sql # 恢复数据库 docker-compose exec -T postgres psql -U postgres km_cloud_db < backup.sql ``` #### Redis备份 ```bash # 保存快照 docker-compose exec redis redis-cli BGSAVE # 备份RDB文件 docker cp redis:/data/dump.rdb ./redis_backup.rdb ``` ### 5. 数据清理 #### 清理过期任务 ```sql -- 删除30天前的已完成任务 DELETE FROM tasks WHERE completed_at < NOW() - INTERVAL '30 days' AND status IN ('SUCCESS', 'FAILED', 'CANCELLED'); ``` #### 清理过期日志 ```bash # 清理30天前的日志 find ./logs -name "*.log" -mtime +30 -delete ``` --- ## 开发文档 ### 1. 本地开发环境搭建 #### 安装依赖 ```bash # 创建虚拟环境 python -m venv venv source venv/bin/activate # Linux/Mac # 或 venv\Scripts\activate # Windows # 安装Python依赖 pip install -r requirements.txt # 或使用conda conda env create -f environment.yml conda activate km_cloud ``` #### 配置开发环境 ```bash # 创建开发配置文件 export FLASK_ENV=development export FLASK_DEBUG=1 export DB_HOST=localhost export DB_NAME=km_cloud_dev export DB_USER=postgres export DB_PASSWORD=password ``` #### 运行开发服务器 ```bash # 运行Flask开发服务器 python app.py # 或使用Flask CLI flask run --host=0.0.0.0 --port=5000 ``` #### 运行测试 ```bash # 运行所有测试 pytest # 运行特定测试 pytest tests/test_auth.py # 查看覆盖率 pytest --cov=. --cov-report=html ``` ### 2. 代码规范 #### Python代码规范 - 遵循PEP 8规范 - 使用类型注解 - 编写文档字符串 - 函数和变量使用蛇形命名 ```python from typing import List, Dict, Optional def get_user_tasks(user_id: int, status: Optional[str] = None) -> List[Dict]: """ 获取用户的任务列表 Args: user_id: 用户ID status: 任务状态过滤(可选) Returns: 任务列表 Raises: ValueError: 当user_id无效时 """ if user_id <= 0: raise ValueError("Invalid user_id") query = Task.query.filter_by(user_id=user_id) if status: query = query.filter_by(status=status) return [task.to_dict() for task in query.all()] ``` #### JavaScript代码规范 - 使用ES6+语法 - 函数使用驼峰命名 - 常量使用全大写下划线分隔 ```javascript // 好的示例 const MAX_UPLOAD_SIZE = 100 * 1024 * 1024; function uploadFile(file) { if (file.size > MAX_UPLOAD_SIZE) { showError('文件大小超出限制'); return false; } // ... } ``` ### 3. 添加新工具 #### 步骤1: 创建工具配置文件 在 `tool_configs/` 目录下创建配置文件: ```yaml # tool_configs/samtools.yml id: samtools name: Samtools version: 1.15 description: Tools for dealing with SAM, BAM and CRAM files category: sequence_analysis parameters: - name: input_file label: Input BAM/SAM File type: file required: true description: Input alignment file in BAM or SAM format accept: [".bam", ".sam"] - name: operation label: Operation type: select required: true default: view options: - value: view label: View - value: sort label: Sort - value: index label: Index description: Samtools operation to perform - name: reference label: Reference Genome type: file required: false description: Reference genome file (for indexing) accept: [".fasta", ".fa"] ``` #### 步骤2: 实现工具适配器 在 `biopipe_cloud/adapters/` 目录下创建适配器: ```python # biopipe_cloud/adapters/samtools_adapter.py from pathlib import Path from typing import Dict, Any import subprocess import logging logger = logging.getLogger(__name__) class SamtoolsAdapter: """Samtools工具适配器""" def __init__(self, config: Dict[str, Any]): self.config = config self.tool_path = "/usr/local/bin/samtools" def validate_parameters(self, params: Dict[str, Any]) -> bool: """验证参数""" if 'input_file' not in params: raise ValueError("缺少必需参数: input_file") input_file = Path(params['input_file']) if not input_file.exists(): raise ValueError(f"输入文件不存在: {params['input_file']}") return True def run(self, params: Dict[str, Any], output_dir: str) -> Dict[str, Any]: """运行工具""" self.validate_parameters(params) operation = params.get('operation', 'view') input_file = params['input_file'] output_file = Path(output_dir) / f"{operation}_output.txt" cmd = [self.tool_path, operation, input_file] logger.info(f"执行命令: {' '.join(cmd)}") result = subprocess.run( cmd, capture_output=True, text=True, timeout=3600 ) if result.returncode != 0: raise Exception(f"Samtools执行失败: {result.stderr}") # 写入输出文件 output_file.write_text(result.stdout) return { 'status': 'success', 'output_file': str(output_file), 'stdout': result.stdout, 'stderr': result.stderr } ``` #### 步骤3: 注册工具 在 `app.py` 中注册工具: ```python from biopipe_cloud.adapters.samtools_adapter import SamtoolsAdapter # 加载工具配置 tools_config = load_tools_config() # 注册工具适配器 tool_adapters = { 'blast': BlastAdapter(tools_config['blast']), 'bowtie2': Bowtie2Adapter(tools_config['bowtie2']), 'samtools': SamtoolsAdapter(tools_config['samtools']), } ``` #### 步骤4: 测试工具 ```python # tests/test_samtools_adapter.py import pytest from biopipe_cloud.adapters.samtools_adapter import SamtoolsAdapter def test_samtools_adapter(): config = { 'name': 'Samtools', 'version': '1.15' } adapter = SamtoolsAdapter(config) # 测试参数验证 with pytest.raises(ValueError): adapter.validate_parameters({}) # 测试参数验证成功 assert adapter.validate_parameters({ 'input_file': '/path/to/test.bam', 'operation': 'view' }) ``` ### 4. API文档生成 使用Swagger/OpenAPI生成API文档: ```python from flasgger import Swagger app = Flask(__name__) swagger = Swagger(app, template={ "info": { "title": "生物信息云平台 API", "version": "1.0.0", "description": "Bioinformatics Cloud Platform API Documentation" } }) @app.route('/api/tools', methods=['GET']) def get_tools(): """ 获取工具列表 --- tags: - 工具管理 responses: 200: description: 成功返回工具列表 """ tools = Tool.query.all() return jsonify([tool.to_dict() for tool in tools]) ``` 访问 `http://localhost:5000/apidocs` 查看API文档。 --- ## 常见问题 ### 1. 部署相关问题 **Q: Docker容器启动失败?** A: 检查以下几点: ```bash # 查看容器日志 docker-compose logs # 检查端口占用 netstat -tlnp | grep # 检查磁盘空间 df -h ``` **Q: 数据库连接失败?** A: 确认以下几点: 1. 数据库容器是否正常运行:`docker-compose ps` 2. 环境变量是否正确配置 3. 数据库密码是否正确 4. 网络连接是否正常 **Q: 文件上传失败?** A: 检查: 1. 文件大小是否超过限制(默认100MB) 2. 存储空间是否充足 3. 文件格式是否允许 4. 用户配额是否已用完 ### 2. 使用相关问题 **Q: 如何增加用户存储配额?** A: 通过数据库直接更新: ```sql UPDATE users SET quota = WHERE id = ; ``` 或在管理界面修改(如果有该功能)。 **Q: 任务执行超时怎么办?** A: 调整Celery配置: ```python app.conf.task_time_limit = 7200 # 增加到2小时 ``` **Q: 如何重置用户密码?** A: 通过Python脚本: ```python from werkzeug.security import generate_password_hash from models import User user = User.query.filter_by(username='username').first() user.password_hash = generate_password_hash('new_password') from app import db db.session.commit() ``` ### 3. 性能相关问题 **Q: 系统响应慢怎么办?** A: 优化建议: 1. 检查数据库查询是否使用了索引 2. 启用Redis缓存 3. 增加Worker数量 4. 使用CDN加速静态资源 5. 启用Gzip压缩 **Q: 内存占用过高?** A: 解决方案: 1. 限制Celery并发数:`worker_concurrency = 2` 2. 定期清理过期任务和日志 3. 使用分页查询避免加载大量数据 4. 优化数据库查询 --- ## 更新日志 ### v1.0.0 (2024-01-05) **新功能:** - ✨ 初始版本发布 - ✨ 用户认证与授权系统 - ✨ 文件管理功能(集成FileBrowser) - ✨ 任务调度系统(Celery + Flower) - ✨ 工具管理模块 - ✨ 项目管理功能 - ✨ 监控与日志系统 **技术特性:** - 🎨 基于Flask 2.0+开发 - 🎨 Docker容器化部署 - 🎨 PostgreSQL + ClickHouse + Redis多数据库支持 - 🎨 Tailwind CSS现代化UI - 🎨 RESTful API设计 ### 计划中的功能 - 📋 更多生信工具集成 - 📋 结果可视化图表 - 📋 工作流编辑器 - 📋 协作功能增强 - 📋 移动端适配 - 📋 多语言支持 --- ## 贡献指南 欢迎贡献代码、报告问题或提出建议! ### 贡献流程 1. Fork本仓库 2. 创建特性分支:`git checkout -b feature/your-feature` 3. 提交更改:`git commit -m 'Add some feature'` 4. 推送到分支:`git push origin feature/your-feature` 5. 创建Pull Request ### 代码规范 - 遵循现有代码风格 - 编写测试用例 - 更新相关文档 - 添加适当的注释 ### 问题报告 报告问题时请提供: - 问题详细描述 - 复现步骤 - 预期行为 - 实际行为 - 环境信息(操作系统、Python版本等) - 相关日志或截图 --- ## 许可证 本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件 --- ## 联系方式 - **项目主页**: [GitHub Repository](https://github.com/yourusername/km_cloud) - **问题反馈**: [GitHub Issues](https://github.com/yourusername/km_cloud/issues) - **邮件联系**: your-email@example.com - **官方网站**: https://your-website.com --- ## 致谢 感谢以下开源项目的支持: - [Flask](https://flask.palletsprojects.com/) - Python Web框架 - [Celery](https://docs.celeryproject.org/) - 分布式任务队列 - [FileBrowser](https://filebrowser.org/) - 文件管理服务 - [Tailwind CSS](https://tailwindcss.com/) - CSS框架 - [Docker](https://www.docker.com/) - 容器技术 --- ## 支持我们 如果这个项目对您有帮助,欢迎: - ⭐ 给项目点个Star - 🐦 在社交媒体分享 - 💰 提供资金支持 - 📝 贡献代码或文档 --- **© 2024 生物信息云平台团队. 保留所有权利。**