refactor: 统一启动脚本到planet.sh,修复resetView调用

- 新增planet.sh统一管理start/stop/restart/health/log命令
- docker-compose.yml只保留postgres和redis
- controls.js点击事件调用resetView函数
This commit is contained in:
rayd1o
2026-03-18 18:09:12 +08:00
parent 3b0e9dec5a
commit 11a9dda942
6 changed files with 133 additions and 295 deletions

View File

@@ -31,51 +31,6 @@ services:
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: planet_backend
ports:
- "8000:8000"
env_file:
- .env
environment:
- DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres:5432/planet_db
- REDIS_URL=redis://redis:6379/0
- SECRET_KEY=your-secret-key-change-in-production
- CORS_ORIGINS=["http://localhost:3000","http://0.0.0.0:3000","http://frontend:3000"]
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- ./backend:/app
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: planet_frontend
ports:
- "3000:3000"
environment:
- VITE_API_URL=http://backend:8000/api/v1
- VITE_WS_URL=ws://backend:8000/ws
volumes:
- ./frontend/public:/app/public
depends_on:
backend:
condition: service_healthy
stdin_open: true
tty: true
volumes:
postgres_data:
redis_data:

View File

@@ -185,27 +185,7 @@ function setupRotateControls(camera, earth) {
});
document.getElementById('reset-view').addEventListener('click', function() {
if (!earthObj) return;
const startRotX = earthObj.rotation.x;
const startRotY = earthObj.rotation.y;
const startZoom = zoomLevel;
const targetRotX = 23.5 * Math.PI / 180;
const targetRotY = 0;
const targetZoom = 1.0;
animateValue(0, 1, 800, (progress) => {
const ease = 1 - Math.pow(1 - progress, 3);
earthObj.rotation.x = startRotX + (targetRotX - startRotX) * ease;
earthObj.rotation.y = startRotY + (targetRotY - startRotY) * ease;
zoomLevel = startZoom + (targetZoom - startZoom) * ease;
camera.position.z = CONFIG.defaultCameraZ / zoomLevel;
updateZoomDisplay(zoomLevel, camera.position.z.toFixed(0));
}, () => {
zoomLevel = 1.0;
showStatusMessage('视图已重置', 'info');
});
resetView(camera);
});
}

132
planet.sh Executable file
View File

@@ -0,0 +1,132 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
start() {
echo -e "${BLUE}🚀 启动智能星球计划...${NC}"
echo -e "${BLUE}🗄️ 启动数据库...${NC}"
docker start planet_postgres planet_redis 2>/dev/null || docker-compose up -d postgres redis
sleep 3
echo -e "${BLUE}🔧 启动后端...${NC}"
pkill -f "uvicorn" 2>/dev/null || true
cd "$SCRIPT_DIR/backend"
PYTHONPATH="$SCRIPT_DIR/backend" nohup python3 -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload > /tmp/planet_backend.log 2>&1 &
BACKEND_PID=$!
sleep 3
if ! curl -s http://localhost:8000/health > /dev/null 2>&1; then
echo -e "${RED}❌ 后端启动失败${NC}"
tail -10 /tmp/planet_backend.log
exit 1
fi
echo -e "${BLUE}🌐 启动前端...${NC}"
pkill -f "vite" 2>/dev/null || true
pkill -f "bun run dev" 2>/dev/null || true
cd "$SCRIPT_DIR/frontend"
nohup bun run dev --port 3000 > /tmp/planet_frontend.log 2>&1 &
sleep 3
echo ""
echo -e "${GREEN}✅ 启动完成!${NC}"
echo " 前端: http://localhost:3000"
echo " 后端: http://localhost:8000"
}
stop() {
echo -e "${YELLOW}🛑 停止服务...${NC}"
pkill -f "uvicorn" 2>/dev/null || true
pkill -f "vite" 2>/dev/null || true
pkill -f "bun run dev" 2>/dev/null || true
docker stop planet_postgres planet_redis 2>/dev/null || true
echo -e "${GREEN}✅ 已停止${NC}"
}
restart() {
stop
sleep 1
start
}
health() {
echo "📊 容器状态:"
docker ps --filter "name=planet_" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "🔍 服务状态:"
if curl -s http://localhost:8000/health > /dev/null 2>&1; then
echo -e " 后端: ${GREEN}✅ 运行中${NC}"
else
echo -e " 后端: ${RED}❌ 未运行${NC}"
fi
if curl -s http://localhost:3000 > /dev/null 2>&1; then
echo -e " 前端: ${GREEN}✅ 运行中${NC}"
else
echo -e " 前端: ${RED}❌ 未运行${NC}"
fi
}
log() {
case "$1" in
-f|--frontend)
echo "📝 前端日志 (Ctrl+C 退出):"
tail -f /tmp/planet_frontend.log
;;
-b|--backend)
echo "📝 后端日志 (Ctrl+C 退出):"
tail -f /tmp/planet_backend.log
;;
*)
echo "📝 最近日志:"
echo "--- 后端 ---"
tail -20 /tmp/planet_backend.log 2>/dev/null || echo "无日志"
echo "--- 前端 ---"
tail -20 /tmp/planet_frontend.log 2>/dev/null || echo "无日志"
;;
esac
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
health)
health
;;
log)
log "$2"
;;
*)
echo "用法: ./planet.sh {start|stop|restart|health|log}"
echo ""
echo "命令:"
echo " start 启动服务"
echo " stop 停止服务"
echo " restart 重启服务"
echo " health 检查健康状态"
echo " log 查看日志"
echo " log -f 查看前端日志"
echo " log -b 查看后端日志"
;;
esac

View File

@@ -1,33 +0,0 @@
#!/bin/bash
# Planet 重启脚本 - 使用 volume 映射,代码改动自动同步
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "🔄 重启智能星球计划..."
echo ""
# 停止并重建容器volume 映射会自动同步代码)
echo "🛑 停止容器..."
docker-compose down
echo "🚀 启动服务..."
docker-compose up -d
# 等待服务就绪
echo "⏳ 等待服务就绪..."
sleep 10
# 验证服务
echo ""
echo "📊 服务状态:"
docker ps --format "table {{.Names}}\t{{.Status}}"
echo ""
echo "✅ 完成!"
echo " 前端: http://localhost:3000"
echo " 后端: http://localhost:8000"
echo ""
echo "💡 代码改动会自动同步,无需重启"

158
start.sh
View File

@@ -1,158 +0,0 @@
#!/bin/bash
# Planet 一键启动脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "🚀 启动智能星球计划..."
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 检查 Docker 服务
if ! command -v docker &> /dev/null; then
echo -e "${RED}❌ Docker 未安装,请先安装 Docker${NC}"
exit 1
fi
if ! docker info &> /dev/null; then
echo -e "${RED}❌ Docker 服务未运行,请先启动 Docker${NC}"
exit 1
fi
# 检查并安装 uv
if ! command -v uv &> /dev/null; then
echo -e "${YELLOW}📦 安装 uv...${NC}"
curl -Ls https://astral.sh/uv | sh
export PATH="$HOME/.cargo/bin:$PATH"
fi
# 检查 npm
if ! command -v npm &> /dev/null; then
echo -e "${RED}❌ npm 未安装,请先安装 Node.js${NC}"
exit 1
fi
# 启动基础设施 (PostgreSQL + Redis)
echo -e "${BLUE}🗄️ 启动数据库...${NC}"
# 检查 docker compose vs docker-compose
if command -v docker-compose &> /dev/null; then
docker-compose up -d postgres redis || true
else
docker compose up -d postgres redis || true
fi
# 等待数据库就绪
echo -e "${YELLOW}⏳ 等待数据库就绪...${NC}"
sleep 5
# 检查数据库是否就绪
MAX_RETRIES=10
RETRY_COUNT=0
# 检查 docker compose vs docker-compose
if command -v docker-compose &> /dev/null; then
while ! docker exec planet_postgres pg_isready -U postgres &> /dev/null; do
RETRY_COUNT=$((RETRY_COUNT + 1))
if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then
echo -e "${RED}❌ 数据库启动超时${NC}"
exit 1
fi
echo -e "${YELLOW} 等待数据库... ($RETRY_COUNT/$MAX_RETRIES)${NC}"
sleep 2
done
else
while ! docker exec planet_postgres pg_isready -U postgres &> /dev/null; do
RETRY_COUNT=$((RETRY_COUNT + 1))
if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then
echo -e "${RED}❌ 数据库启动超时${NC}"
exit 1
fi
echo -e "${YELLOW} 等待数据库... ($RETRY_COUNT/$MAX_RETRIES)${NC}"
sleep 2
done
fi
echo -e "${GREEN}✅ 数据库已就绪${NC}"
# 同步 Python 依赖
echo -e "${BLUE}🐍 同步 Python 依赖...${NC}"
uv sync
# 初始化数据库
echo -e "${BLUE}🗃️ 初始化数据库...${NC}"
PYTHONPATH="$SCRIPT_DIR/backend" python "$SCRIPT_DIR/backend/scripts/init_admin.py" > /dev/null 2>&1 || true
# 设置环境变量
export PYTHONPATH="$SCRIPT_DIR/backend"
# 启动后端服务
echo -e "${BLUE}🔧 启动后端服务...${NC}"
# 检查端口 8000 是否被占用
if lsof -i :8000 > /dev/null 2>&1 || netstat -tlnp 2>/dev/null | grep -q ":8000" || ss -tlnp 2>/dev/null | grep -q ":8000"; then
echo -e "${RED}❌ 端口 8000 已被占用,请先停止占用端口的进程${NC}"
echo " 使用命令: ./kill_port.sh 8000 或 lsof -i :8000 查看"
exit 1
fi
cd "$SCRIPT_DIR/backend"
PYTHONPATH="$SCRIPT_DIR/backend" nohup python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 > /tmp/planet_backend.log 2>&1 &
BACKEND_PID=$!
cd "$SCRIPT_DIR"
echo " 后端 PID: $BACKEND_PID"
# 等待后端启动
echo -e "${YELLOW}⏳ 等待后端服务启动...${NC}"
sleep 5
# 检查后端是否正常运行
if ! curl -s http://localhost:8000/health > /dev/null 2>&1; then
echo -e "${RED}❌ 后端服务启动失败,查看日志: tail /tmp/planet_backend.log${NC}"
tail -20 /tmp/planet_backend.log
exit 1
fi
echo -e "${GREEN}✅ 后端服务已启动${NC}"
# 检查并安装前端依赖
if [ ! -d "frontend/node_modules" ]; then
echo -e "${YELLOW}📦 安装前端依赖...${NC}"
cd frontend
npm install
cd ..
fi
# 启动前端服务
echo -e "${BLUE}🌐 启动前端服务...${NC}"
cd frontend
npm run dev > /tmp/planet_frontend.log 2>&1 &
FRONTEND_PID=$!
echo " 前端 PID: $FRONTEND_PID"
cd ..
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}✅ 智能星球计划启动完成!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e "${BLUE}🌐 访问地址:${NC}"
echo " 后端: http://localhost:8000"
echo " API文档: http://localhost:8000/docs"
echo " 前端: http://localhost:3000"
echo ""
echo -e "${BLUE}📝 服务进程:${NC}"
echo " 后端 PID: $BACKEND_PID"
echo " 前端 PID: $FRONTEND_PID"
echo ""
echo -e "${BLUE}📝 日志查看:${NC}"
echo " tail -f /tmp/planet_backend.log"
echo " tail -f /tmp/planet_frontend.log"
echo ""
echo -e "${BLUE}🛑 停止服务:${NC}"
echo " pkill -f 'uvicorn' # 停止后端"
echo " pkill -f 'vite' # 停止前端"

38
stop.sh
View File

@@ -1,38 +0,0 @@
#!/bin/bash
# Planet 停止脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "🛑 停止智能星球计划..."
# 停止后端服务
if pgrep -f "uvicorn" > /dev/null; then
echo "🔧 停止后端服务..."
pkill -f "uvicorn" || true
echo "✅ 后端服务已停止"
else
echo " 后端服务未运行"
fi
# 停止前端服务
if pgrep -f "vite" > /dev/null; then
echo "🌐 停止前端服务..."
pkill -f "vite" || true
echo "✅ 前端服务已停止"
else
echo " 前端服务未运行"
fi
# 停止 Docker 容器
echo "🗄️ 停止数据库容器..."
if command -v docker-compose &> /dev/null; then
docker-compose stop postgres redis || true
else
docker compose stop postgres redis || true
fi
echo ""
echo "✅ 所有服务已停止"