#!/bin/bash # stop_all.sh - 停止所有服务(API + 前端) # 支持停止 Vite 开发服务器 set -e LOG_DIR="logs" PID_FILE_API="$LOG_DIR/api.pid" PID_FILE_FRONTEND="$LOG_DIR/frontend.pid" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' # 加载配置 if [ -f ".env" ]; then export $(grep -v '^#' .env | grep -E '^FRONTEND_PORT' | xargs 2>/dev/null || true) fi FRONTEND_PORT=${FRONTEND_PORT:-3000} echo "" echo -e "${CYAN}========================================${NC}" echo -e "${CYAN} AI+合规智能中枢 - 停止服务${NC}" echo -e "${CYAN}========================================${NC}" echo "" # ===== 停止API服务 ===== echo -e "${YELLOW}[1/2] 停止API服务...${NC}" if [ -f "$PID_FILE_API" ]; then PID=$(cat $PID_FILE_API) if ps -p $PID > /dev/null 2>&1; then echo "正在停止API服务 (PID: $PID)..." kill $PID sleep 2 if ps -p $PID > /dev/null 2>&1; then echo "进程未响应,强制终止..." kill -9 $PID fi rm -f $PID_FILE_API echo -e "${GREEN}✓ API服务已停止${NC}" else echo "进程已不存在,清理PID文件" rm -f $PID_FILE_API fi else echo -e "${YELLOW}API PID文件不存在${NC}" # 尝试查找并停止所有uvicorn进程 UVICORN_PIDS=$(pgrep -f "uvicorn src.api.main" 2>/dev/null || true) if [ -n "$UVICORN_PIDS" ]; then echo "发现运行中的uvicorn进程: $UVICORN_PIDS" kill $UVICORN_PIDS 2>/dev/null || true echo -e "${GREEN}✓ 已停止uvicorn进程${NC}" else echo -e "${YELLOW}未发现运行中的API服务${NC}" fi fi echo "" # ===== 停止前端服务 ===== echo -e "${YELLOW}[2/2] 停止前端服务...${NC}" STOPPED=false # 方法1: 通过PID文件停止 if [ -f "$PID_FILE_FRONTEND" ]; then PID=$(cat $PID_FILE_FRONTEND) if ps -p $PID > /dev/null 2>&1; then echo "正在停止前端服务 (PID: $PID)..." kill $PID sleep 2 if ps -p $PID > /dev/null 2>&1; then echo "进程未响应,强制终止..." kill -9 $PID fi rm -f $PID_FILE_FRONTEND echo -e "${GREEN}✓ 前端服务已停止${NC}" STOPPED=true else echo "进程已不存在,清理PID文件" rm -f $PID_FILE_FRONTEND fi fi # 方法2: 通过进程名查找并停止(如果PID文件方式未成功) if [ "$STOPPED" = false ]; then # 查找 Vite 进程 VITE_PIDS=$(pgrep -f "vite" 2>/dev/null || true) if [ -n "$VITE_PIDS" ]; then echo "发现运行中的Vite进程: $VITE_PIDS" kill $VITE_PIDS 2>/dev/null || true sleep 1 # 检查是否还有残留进程 VITE_REMAIN=$(pgrep -f "vite" 2>/dev/null || true) if [ -n "$VITE_REMAIN" ]; then echo "强制终止残留进程..." kill -9 $VITE_REMAIN 2>/dev/null || true fi echo -e "${GREEN}✓ 已停止Vite进程${NC}" STOPPED=true fi # 查找 npm/node 进程(启动Vite的父进程) NPM_PIDS=$(pgrep -f "npm run dev" 2>/dev/null || true) if [ -n "$NPM_PIDS" ]; then echo "发现运行中的npm进程: $NPM_PIDS" kill $NPM_PIDS 2>/dev/null || true echo -e "${GREEN}✓ 已停止npm进程${NC}" STOPPED=true fi # 查找 node 进程监听前端端口 NODE_PORT_PIDS=$(lsof -ti:$FRONTEND_PORT 2>/dev/null || true) if [ -n "$NODE_PORT_PIDS" ]; then echo "发现监听端口 $FRONTEND_PORT 的进程: $NODE_PORT_PIDS" kill $NODE_PORT_PIDS 2>/dev/null || true echo -e "${GREEN}✓ 已停止端口监听进程${NC}" STOPPED=true fi # 查找 HTTP 服务器(备用) HTTP_PIDS=$(pgrep -f "http.server $FRONTEND_PORT" 2>/dev/null || true) if [ -n "$HTTP_PIDS" ]; then echo "发现运行中的HTTP服务器: $HTTP_PIDS" kill $HTTP_PIDS 2>/dev/null || true echo -e "${GREEN}✓ 已停止HTTP服务${NC}" STOPPED=true fi fi if [ "$STOPPED" = false ]; then echo -e "${YELLOW}未发现运行中的前端服务${NC}" fi # 清理PID文件 rm -f $PID_FILE_FRONTEND echo "" echo -e "${CYAN}========================================${NC}" echo -e "${GREEN} 所有服务已停止${NC}" echo -e "${CYAN}========================================${NC}" echo ""