143 lines
4.0 KiB
Bash
Executable File
143 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# ZeekerWatchman — 一键启动脚本
|
|
# 自动安装依赖、启动后端和前端服务
|
|
#
|
|
set -e
|
|
|
|
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
BACKEND_PORT=8765
|
|
FRONTEND_PORT=3000
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
cleanup() {
|
|
echo -e "\n${BLUE}正在停止服务...${NC}"
|
|
kill $BACKEND_PID 2>/dev/null || true
|
|
kill $FRONTEND_PID 2>/dev/null || true
|
|
echo -e "${GREEN}服务已停止${NC}"
|
|
exit 0
|
|
}
|
|
trap cleanup SIGINT SIGTERM
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo -e "${BLUE} ZeekerWatchman — 测试用例智能管理平台${NC}"
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo ""
|
|
|
|
# ---- 检查环境 ----
|
|
echo -e "${BLUE}[1/5] 检查运行环境...${NC}"
|
|
|
|
if ! command -v python3 &>/dev/null; then
|
|
echo -e "${RED}错误: 未找到 python3${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e " Python: $(python3 --version)"
|
|
|
|
if ! command -v node &>/dev/null; then
|
|
echo -e "${RED}错误: 未找到 node${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e " Node: $(node --version)"
|
|
echo -e " npm: $(npm --version)"
|
|
|
|
# ---- 安装 Python 依赖 ----
|
|
echo -e "\n${BLUE}[2/5] 安装 Python 依赖...${NC}"
|
|
cd "$ROOT_DIR"
|
|
pip install -q -r server/requirements.txt 2>&1 | tail -1 || {
|
|
echo -e "${RED}Python 依赖安装失败,请检查 server/requirements.txt${NC}"
|
|
exit 1
|
|
}
|
|
echo -e "${GREEN} Python 依赖就绪${NC}"
|
|
|
|
# ---- 安装前端依赖 ----
|
|
echo -e "\n${BLUE}[3/5] 安装前端依赖...${NC}"
|
|
cd "$ROOT_DIR/web"
|
|
if [ ! -d "node_modules" ]; then
|
|
npm install --silent 2>&1 | tail -1
|
|
fi
|
|
echo -e "${GREEN} 前端依赖就绪${NC}"
|
|
|
|
# ---- 检查端口 ----
|
|
echo -e "\n${BLUE}[4/5] 检查端口占用...${NC}"
|
|
if lsof -i:$BACKEND_PORT &>/dev/null 2>&1; then
|
|
echo -e " 端口 $BACKEND_PORT 被占用,尝试释放..."
|
|
kill $(lsof -t -i:$BACKEND_PORT) 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
if lsof -i:$FRONTEND_PORT &>/dev/null 2>&1; then
|
|
echo -e " 端口 $FRONTEND_PORT 被占用,尝试释放..."
|
|
kill $(lsof -t -i:$FRONTEND_PORT) 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
echo -e "${GREEN} 端口可用${NC}"
|
|
|
|
# ---- 启动服务 ----
|
|
echo -e "\n${BLUE}[5/5] 启动服务...${NC}"
|
|
|
|
# 后端
|
|
cd "$ROOT_DIR"
|
|
PYTHONPATH=. python -m uvicorn server.main:app \
|
|
--host 0.0.0.0 --port $BACKEND_PORT \
|
|
--log-level info \
|
|
> /tmp/testflow-backend.log 2>&1 &
|
|
BACKEND_PID=$!
|
|
echo -e " 后端 PID: $BACKEND_PID (端口 $BACKEND_PORT)"
|
|
|
|
# 等待后端就绪
|
|
for i in $(seq 1 15); do
|
|
if curl -s http://localhost:$BACKEND_PORT/api/health &>/dev/null; then
|
|
echo -e " ${GREEN}后端就绪 ✓${NC}"
|
|
break
|
|
fi
|
|
if [ $i -eq 15 ]; then
|
|
echo -e " ${RED}后端启动超时,查看日志: tail /tmp/testflow-backend.log${NC}"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
# 前端
|
|
cd "$ROOT_DIR/web"
|
|
npx next dev --port $FRONTEND_PORT --hostname 0.0.0.0 \
|
|
> /tmp/testflow-frontend.log 2>&1 &
|
|
FRONTEND_PID=$!
|
|
echo -e " 前端 PID: $FRONTEND_PID (端口 $FRONTEND_PORT)"
|
|
|
|
# 等待前端就绪
|
|
for i in $(seq 1 20); do
|
|
if curl -s -o /dev/null -w "%{http_code}" http://localhost:$FRONTEND_PORT 2>/dev/null | grep -q "200"; then
|
|
echo -e " ${GREEN}前端就绪 ✓${NC}"
|
|
break
|
|
fi
|
|
if [ $i -eq 20 ]; then
|
|
echo -e " ${RED}前端启动超时,查看日志: tail /tmp/testflow-frontend.log${NC}"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
# ---- 完成 ----
|
|
echo ""
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "${GREEN} ZeekerWatchman 启动完成!${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo ""
|
|
echo -e " 前端页面: ${BLUE}http://localhost:$FRONTEND_PORT${NC}"
|
|
echo -e " 后端 API: ${BLUE}http://localhost:$BACKEND_PORT/api/health${NC}"
|
|
echo -e " API 文档: ${BLUE}http://localhost:$BACKEND_PORT/docs${NC}"
|
|
echo ""
|
|
echo -e " 后端日志: tail -f /tmp/testflow-backend.log"
|
|
echo -e " 前端日志: tail -f /tmp/testflow-frontend.log"
|
|
echo ""
|
|
echo -e " 按 ${RED}Ctrl+C${NC} 停止所有服务"
|
|
echo ""
|
|
|
|
# 保持前台运行
|
|
wait
|