diff --git a/code/backend/api/__init__.py b/code/backend/api/__init__.py new file mode 100644 index 0000000..23ca7a6 --- /dev/null +++ b/code/backend/api/__init__.py @@ -0,0 +1 @@ +default_app_config = 'api.apps.ApiConfig' diff --git a/code/backend/api/apps.py b/code/backend/api/apps.py new file mode 100644 index 0000000..bc06421 --- /dev/null +++ b/code/backend/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/code/backend/api/urls.py b/code/backend/api/urls.py new file mode 100644 index 0000000..3446a04 --- /dev/null +++ b/code/backend/api/urls.py @@ -0,0 +1,12 @@ +""" +API URL configuration. +""" +from django.urls import path +from . import views + +urlpatterns = [ + path('lobsters/', views.lobster_list, name='lobster-list'), + path('lobsters//', views.lobster_detail, name='lobster-detail'), + path('lobsters//memory/', views.lobster_memory, name='lobster-memory'), + path('tools/', views.tools_list, name='tools-list'), +] diff --git a/code/backend/api/views.py b/code/backend/api/views.py new file mode 100644 index 0000000..926956b --- /dev/null +++ b/code/backend/api/views.py @@ -0,0 +1,67 @@ +""" +API views for lobster monitoring. +""" +from rest_framework.decorators import api_view +from rest_framework.response import Response +from datetime import datetime +import os + +# 龙虾配置 +LOBSTERS = [ + {'id': 1, 'name': '飞行侠', 'emoji': '🦸', 'port': 18789, 'specialty': '主力/通用', 'container': 'openclaw-instance2'}, + {'id': 2, 'name': '道童', 'emoji': '☯️', 'port': 18889, 'specialty': '道德经注解', 'container': 'openclaw-gateway-2'}, + {'id': 3, 'name': '墨子', 'emoji': '🔧', 'port': 18689, 'specialty': '代码专家', 'container': 'openclaw-coder'}, + {'id': 4, 'name': '织网者', 'emoji': '🕸️', 'port': 18589, 'specialty': '网站制作', 'container': 'openclaw-web'}, + {'id': 5, 'name': '费曼', 'emoji': '⚛️', 'port': 18989, 'specialty': '物理研究', 'container': 'openclaw-physics'}, + {'id': 6, 'name': '守望者', 'emoji': '👁️', 'port': 18080, 'specialty': '舰队监控', 'container': 'openclaw-watcher'}, +] + +@api_view(['GET']) +def lobster_list(request): + """获取所有龙虾状态""" + lobsters = [] + for lobster in LOBSTERS: + # 检查端口状态(简化版本,实际应该检查端口) + status = 'healthy' + lobsters.append({ + **lobster, + 'status': status, + 'last_check': datetime.now().isoformat() + }) + return Response(lobsters) + +@api_view(['GET']) +def lobster_detail(request, lobster_id): + """获取单个龙虾详情""" + for lobster in LOBSTERS: + if lobster['id'] == lobster_id: + return Response({ + **lobster, + 'status': 'healthy', + 'workspace': f'/home/node/.openclaw/workspace/{lobster["name"].lower()}', + 'last_check': datetime.now().isoformat() + }) + return Response({'error': '龙虾不存在'}, status=404) + +@api_view(['GET']) +def lobster_memory(request, lobster_id): + """获取龙虾记忆""" + # 这里简化处理,实际应该读取文件 + return Response({ + 'lobster_id': lobster_id, + 'memory': '# 长期记忆\n\n记忆内容加载中...', + 'daily_memories': [] + }) + +@api_view(['GET']) +def tools_list(request): + """获取工具列表""" + tools = [ + { + 'name': 'Git 版本控制', + 'status': 'running', + 'description': '代码版本管理服务', + 'url': 'https://xjp.datalibstar.com/flying-hero/openclaw-monitor.git' + } + ] + return Response(tools) diff --git a/code/backend/backend/settings.py b/code/backend/backend/settings.py new file mode 100644 index 0000000..75c0f76 --- /dev/null +++ b/code/backend/backend/settings.py @@ -0,0 +1,96 @@ +""" +Django settings for lobster_monitor project. +""" + +from pathlib import Path + +BASE_DIR = Path(__file__).resolve().parent.parent + +SECRET_KEY = 'django-insecure-lobster-monitor-dev-key' + +DEBUG = True + +ALLOWED_HOSTS = ['*'] + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rest_framework', + 'corsheaders', + 'api', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'backend.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'backend.wsgi.application' + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +LANGUAGE_CODE = 'zh-hans' +TIME_ZONE = 'Asia/Shanghai' +USE_I18N = True +USE_TZ = True + +STATIC_URL = 'static/' +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +# CORS 配置 +CORS_ALLOW_ALL_ORIGINS = True + +# REST Framework 配置 +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.AllowAny', + ] +} diff --git a/code/backend/backend/urls.py b/code/backend/backend/urls.py new file mode 100644 index 0000000..450d257 --- /dev/null +++ b/code/backend/backend/urls.py @@ -0,0 +1,10 @@ +""" +URL configuration for lobster_monitor project. +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('api/', include('api.urls')), +] diff --git a/code/backend/requirements.txt b/code/backend/requirements.txt new file mode 100644 index 0000000..07079d8 --- /dev/null +++ b/code/backend/requirements.txt @@ -0,0 +1,3 @@ +djangorestframework==3.14.0 +django-cors-headers==4.3.0 +Django==4.2.0 diff --git a/docs/部署指南.md b/docs/部署指南.md new file mode 100644 index 0000000..494c003 --- /dev/null +++ b/docs/部署指南.md @@ -0,0 +1,124 @@ +# 部署指南 + +## 🚀 快速部署 + +### 1. 安装依赖 + +#### 后端 +```bash +cd code/backend +pip3 install -r requirements.txt +``` + +#### 前端 +```bash +cd code/frontend +npm install +``` + +### 2. 启动服务 + +#### 方法一:使用启动脚本 +```bash +chmod +x start.sh +./start.sh +``` + +#### 方法二:手动启动 +```bash +# 启动后端 +cd code/backend +python3 manage.py runserver 0.0.0.0:8000 + +# 启动前端(新终端) +cd code/frontend +npm start +# 或 +python3 -m http.server 3000 +``` + +### 3. 访问 + +- **前端**: http://localhost:3000 +- **后端 API**: http://localhost:8000/api/ +- **API 文档**: http://localhost:8000/api/lobsters/ + +## 📊 API 接口 + +### 获取龙虾列表 +```bash +curl http://localhost:8000/api/lobsters/ +``` + +### 获取龙虾详情 +```bash +curl http://localhost:8000/api/lobsters/1/ +``` + +### 获取龙虾记忆 +```bash +curl http://localhost:8000/api/lobsters/1/memory/ +``` + +### 获取工具列表 +```bash +curl http://localhost:8000/api/tools/ +``` + +## 🔧 配置 + +### 环境变量 +- `DEBUG`: 调试模式(默认 True) +- `SECRET_KEY`: Django 密钥 +- `ALLOWED_HOSTS`: 允许的主机 + +### 数据库 +默认使用 SQLite,无需配置。 + +## 📝 日志 + +- 后端日志:终端输出 +- 前端日志:浏览器控制台 + +## 🐛 故障排查 + +### 端口被占用 +```bash +# 查看占用端口的进程 +lsof -i :8000 +lsof -i :3000 + +# 杀死进程 +kill -9 +``` + +### 依赖问题 +```bash +# 重新安装依赖 +pip3 install -r requirements.txt --force-reinstall +npm install --force +``` + +## 📦 生产部署 + +### 使用 Gunicorn +```bash +pip3 install gunicorn +gunicorn backend.wsgi:application --bind 0.0.0.0:8000 +``` + +### 使用 Nginx 反向代理 +```nginx +server { + listen 80; + server_name your-domain.com; + + location / { + proxy_pass http://localhost:3000; + } + + location /api/ { + proxy_pass http://localhost:8000; + } +} +``` diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..204b26a --- /dev/null +++ b/start.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# 龙虾舰队监控中心 - 启动脚本 + +echo "🦞 启动龙虾舰队监控中心..." + +# 启动后端 +echo "📡 启动 Django 后端..." +cd code/backend +python3 manage.py runserver 0.0.0.0:8000 & +BACKEND_PID=$! + +# 等待后端启动 +sleep 3 + +# 启动前端 +echo "🎨 启动前端服务..." +cd ../frontend +python3 -m http.server 3000 & +FRONTEND_PID=$! + +echo "" +echo "✅ 监控中心已启动!" +echo "" +echo "访问地址:" +echo " 前端:http://localhost:3000" +echo " 后端 API: http://localhost:8000/api/" +echo "" +echo "按 Ctrl+C 停止服务" + +# 等待进程 +wait