#!/bin/bash set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$SCRIPT_DIR" PID_DIR="$SCRIPT_DIR/.pids" BACKEND_PID_FILE="$PID_DIR/backend.pid" FRONTEND_PID_FILE="$PID_DIR/frontend.pid" LOG_DIR="$SCRIPT_DIR/logs" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' log() { echo -e "${CYAN}[sql-platform]${NC} $1"; } ok() { echo -e "${GREEN}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } err() { echo -e "${RED}[ERROR]${NC} $1"; } ensure_dirs() { mkdir -p "$PID_DIR" "$LOG_DIR" } is_running() { local pid_file=$1 local name=$2 if [ -f "$pid_file" ]; then local pid=$(cat "$pid_file") if kill -0 "$pid" 2>/dev/null; then return 0 else rm -f "$pid_file" fi fi return 1 } stop_service() { local pid_file=$1 local name=$2 if is_running "$pid_file" "$name"; then local pid=$(cat "$pid_file") log "停止 $name (PID: $pid)..." kill "$pid" 2>/dev/null || true # 等待进程退出 for i in $(seq 1 10); do if ! kill -0 "$pid" 2>/dev/null; then break fi sleep 0.3 done # 强制杀死 if kill -0 "$pid" 2>/dev/null; then kill -9 "$pid" 2>/dev/null || true fi rm -f "$pid_file" ok "$name 已停止" else warn "$name 未运行" fi } stop_all() { stop_service "$FRONTEND_PID_FILE" "前端" stop_service "$BACKEND_PID_FILE" "后端" } start_backend() { if is_running "$BACKEND_PID_FILE" "后端"; then warn "后端已在运行 (PID: $(cat $BACKEND_PID_FILE))" return fi log "启动后端..." cd "$SCRIPT_DIR/backend" if [ ! -d "venv" ]; then log "创建 Python 虚拟环境..." python3 -m venv venv fi source venv/bin/activate if [ ! -f "venv/lib/python*/site-packages/fastapi/__init__.py" ] 2>/dev/null; then log "安装后端依赖..." pip install -r requirements.txt -q 2>&1 | tail -3 fi # 数据库迁移 venv/bin/alembic upgrade head 2>/dev/null || true nohup venv/bin/python -m uvicorn app.main:app \ --host 0.0.0.0 --port 9000 --reload \ > "$LOG_DIR/backend.log" 2>&1 & echo $! > "$BACKEND_PID_FILE" # 等待后端就绪 for i in $(seq 1 15); do if curl -s http://localhost:9000/docs > /dev/null 2>&1; then ok "后端已启动 → http://localhost:9000 (PID: $(cat $BACKEND_PID_FILE))" return fi sleep 0.5 done warn "后端启动中... 查看日志: tail -f $LOG_DIR/backend.log" } start_frontend() { if is_running "$FRONTEND_PID_FILE" "前端"; then warn "前端已在运行 (PID: $(cat $FRONTEND_PID_FILE))" return fi log "启动前端..." cd "$SCRIPT_DIR/frontend" if [ ! -d "node_modules" ]; then log "安装前端依赖..." npm install --silent 2>&1 | tail -3 fi nohup npx vite --host 0.0.0.0 --port 5173 \ > "$LOG_DIR/frontend.log" 2>&1 & echo $! > "$FRONTEND_PID_FILE" # 等待前端就绪 for i in $(seq 1 15); do if curl -s http://localhost:5173 > /dev/null 2>&1; then ok "前端已启动 → http://localhost:5173 (PID: $(cat $FRONTEND_PID_FILE))" return fi sleep 0.5 done warn "前端启动中... 查看日志: tail -f $LOG_DIR/frontend.log" } show_status() { echo "" echo "=== Web-Lite 数据审核平台 状态 ===" echo "" if is_running "$BACKEND_PID_FILE" "后端"; then echo -e " 后端: ${GREEN}● 运行中${NC} PID: $(cat $BACKEND_PID_FILE) → http://localhost:9000" else echo -e " 后端: ${RED}○ 未运行${NC}" fi if is_running "$FRONTEND_PID_FILE" "前端"; then echo -e " 前端: ${GREEN}● 运行中${NC} PID: $(cat $FRONTEND_PID_FILE) → http://localhost:5173" else echo -e " 前端: ${RED}○ 未运行${NC}" fi echo "" echo " API 文档: http://localhost:9000/docs" echo " 默认账号: admin / 123456" echo " 日志目录: $LOG_DIR/" echo "" } show_logs() { local target=${1:-all} case "$target" in backend|b) tail -f "$LOG_DIR/backend.log" ;; frontend|f) tail -f "$LOG_DIR/frontend.log" ;; *) tail -f "$LOG_DIR/backend.log" "$LOG_DIR/frontend.log" ;; esac } case "${1:-start}" in start) ensure_dirs log "=== 启动服务 ===" start_backend start_frontend echo "" ok "全部服务已启动" echo " 前端: http://localhost:5173" echo " 后端: http://localhost:9000" echo " 文档: http://localhost:9000/docs" ;; stop) log "=== 停止服务 ===" stop_all ;; restart) log "=== 重启服务 ===" stop_all sleep 1 ensure_dirs start_backend start_frontend ok "全部服务已重启" ;; status|s) show_status ;; logs|l) show_logs "$2" ;; build) log "=== 构建生产版本 ===" cd "$SCRIPT_DIR/backend" && source venv/bin/activate log "构建后端..." pip install -r requirements.txt -q ok "后端依赖已安装" cd "$SCRIPT_DIR/frontend" log "构建前端..." npm run build ok "前端构建完成 → frontend/dist/" ;; test|t) log "=== 运行测试 ===" cd "$SCRIPT_DIR/backend" && source venv/bin/activate python -m pytest tests/ -v --tb=short "$@" ;; *) echo "用法: ./run.sh {start|stop|restart|status|logs|build|test}" echo "" echo " start 启动前后端服务 (默认)" echo " stop 停止所有服务" echo " restart 重启所有服务" echo " status 查看服务状态" echo " logs 查看日志 (backend/frontend/all)" echo " build 构建生产版本" echo " test 运行后端测试" ;; esac