Refactor code structure for improved readability and maintainability
This commit is contained in:
710
dev.sh
Normal file
710
dev.sh
Normal file
@@ -0,0 +1,710 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
VENV_DIR=".venv"
|
||||
VENV_PYTHON="$VENV_DIR/bin/python"
|
||||
LOG_DIR="logs"
|
||||
API_PID_FILE="$LOG_DIR/api.pid"
|
||||
FRONTEND_PID_FILE="$LOG_DIR/frontend.pid"
|
||||
API_LOG_FILE="$LOG_DIR/api.log"
|
||||
FRONTEND_LOG_FILE="$LOG_DIR/frontend.log"
|
||||
DOCKER_CONTAINERS="milvus minio redis postgres"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
load_env() {
|
||||
if [ -f ".env" ]; then
|
||||
while IFS='=' read -r key value; do
|
||||
key="${key%$'\r'}"
|
||||
value="${value%$'\r'}"
|
||||
|
||||
case "$key" in
|
||||
""|\#*)
|
||||
continue
|
||||
;;
|
||||
API_HOST|API_PORT|FRONTEND_PORT|FRONTEND_MODE)
|
||||
export "$key=$value"
|
||||
;;
|
||||
esac
|
||||
done < ".env"
|
||||
fi
|
||||
|
||||
API_HOST="${API_HOST:-0.0.0.0}"
|
||||
API_PORT="${API_PORT:-8000}"
|
||||
FRONTEND_PORT="${FRONTEND_PORT:-5173}"
|
||||
FRONTEND_MODE="${FRONTEND_MODE:-dev}"
|
||||
}
|
||||
|
||||
ensure_log_dir() {
|
||||
mkdir -p "$LOG_DIR"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo -e "${CYAN} $1${NC}"
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${CYAN}$1${NC}"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}$1${NC}"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}$1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}$1${NC}" >&2
|
||||
}
|
||||
|
||||
die() {
|
||||
error "$1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
is_pid_running() {
|
||||
local pid="$1"
|
||||
[ -n "$pid" ] && ps -p "$pid" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
read_pid() {
|
||||
local pid_file="$1"
|
||||
if [ -f "$pid_file" ]; then
|
||||
cat "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_stale_pid() {
|
||||
local pid_file="$1"
|
||||
local pid
|
||||
pid="$(read_pid "$pid_file")"
|
||||
if [ -n "$pid" ] && ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
port_pid() {
|
||||
local port="$1"
|
||||
|
||||
if command -v lsof > /dev/null 2>&1; then
|
||||
lsof -ti tcp:"$port" 2>/dev/null | head -n 1 || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v ss > /dev/null 2>&1; then
|
||||
ss -lptn "sport = :$port" 2>/dev/null | awk -F 'pid=' 'NR>1 && NF>1 {split($2,a,/,/); print a[1]; exit}' || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v netstat > /dev/null 2>&1; then
|
||||
netstat -lntp 2>/dev/null | awk -v port=":$port" '$4 ~ port {split($7,a,"/"); if (a[1] != "-") {print a[1]; exit}}' || true
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
require_python_bootstrap() {
|
||||
if command -v python3 > /dev/null 2>&1; then
|
||||
PYTHON_BOOTSTRAP="python3"
|
||||
elif command -v python > /dev/null 2>&1; then
|
||||
PYTHON_BOOTSTRAP="python"
|
||||
else
|
||||
die "未找到 Python,请先安装 Python 3.10+。"
|
||||
fi
|
||||
}
|
||||
|
||||
require_venv() {
|
||||
[ -x "$VENV_PYTHON" ] || die "虚拟环境不存在,请先运行 ./dev.sh setup"
|
||||
}
|
||||
|
||||
ensure_frontend_deps() {
|
||||
if [ ! -d "frontend" ]; then
|
||||
die "前端目录不存在: frontend"
|
||||
fi
|
||||
|
||||
if [ ! -d "frontend/node_modules" ] || [ ! -d "frontend/node_modules/vite" ]; then
|
||||
warn "前端依赖不存在或不完整,正在执行 npm install..."
|
||||
npm --prefix frontend install
|
||||
fi
|
||||
}
|
||||
|
||||
validate_frontend_mode() {
|
||||
case "$1" in
|
||||
dev|static)
|
||||
;;
|
||||
*)
|
||||
die "前端模式仅支持 dev 或 static,当前值: $1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_python_version() {
|
||||
local python_cmd="$1"
|
||||
"$python_cmd" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 10) else 1)'
|
||||
}
|
||||
|
||||
run_setup() {
|
||||
load_env
|
||||
ensure_log_dir
|
||||
print_header "AI+合规智能中枢 - 环境初始化"
|
||||
|
||||
require_python_bootstrap
|
||||
|
||||
info "[1/4] 检查 Python 版本"
|
||||
check_python_version "$PYTHON_BOOTSTRAP" || die "需要 Python 3.10+"
|
||||
success "Python 版本检查通过"
|
||||
echo ""
|
||||
|
||||
info "[2/4] 准备虚拟环境"
|
||||
if [ ! -d "$VENV_DIR" ]; then
|
||||
"$PYTHON_BOOTSTRAP" -m venv "$VENV_DIR"
|
||||
success "已创建虚拟环境: $VENV_DIR"
|
||||
else
|
||||
success "虚拟环境已存在: $VENV_DIR"
|
||||
fi
|
||||
|
||||
"$VENV_PYTHON" -m pip install --upgrade pip
|
||||
"$VENV_PYTHON" -m pip install -r backend/requirements.txt
|
||||
success "后端依赖安装完成"
|
||||
echo ""
|
||||
|
||||
info "[3/4] 准备前端依赖"
|
||||
if ! command -v npm > /dev/null 2>&1; then
|
||||
die "未找到 npm,请先安装 Node.js 20+。"
|
||||
fi
|
||||
npm --prefix frontend install
|
||||
success "前端依赖安装完成"
|
||||
echo ""
|
||||
|
||||
info "[4/4] 检查 Docker 基础服务"
|
||||
if command -v docker > /dev/null 2>&1; then
|
||||
local container
|
||||
for container in $DOCKER_CONTAINERS; do
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
|
||||
success "${container}: 运行中"
|
||||
elif docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
|
||||
warn "${container}: 已创建但未运行"
|
||||
else
|
||||
warn "${container}: 未找到容器"
|
||||
fi
|
||||
done
|
||||
else
|
||||
warn "未检测到 Docker,已跳过容器检查"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
success "环境初始化完成"
|
||||
echo "后续常用命令:"
|
||||
echo " ./dev.sh start"
|
||||
echo " ./dev.sh status"
|
||||
echo " ./dev.sh logs api --follow"
|
||||
}
|
||||
|
||||
api_health_ok() {
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
curl -fsS "http://localhost:$API_PORT/health" > /dev/null 2>&1
|
||||
return
|
||||
fi
|
||||
|
||||
require_venv
|
||||
"$VENV_PYTHON" - <<PY > /dev/null 2>&1
|
||||
import sys
|
||||
from urllib.request import urlopen
|
||||
|
||||
try:
|
||||
with urlopen("http://localhost:${API_PORT}/health", timeout=3) as response:
|
||||
body = response.read().decode("utf-8", errors="ignore")
|
||||
sys.exit(0 if "healthy" in body.lower() else 1)
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
PY
|
||||
}
|
||||
|
||||
start_api() {
|
||||
local mode="${1:-background}"
|
||||
load_env
|
||||
ensure_log_dir
|
||||
require_venv
|
||||
cleanup_stale_pid "$API_PID_FILE"
|
||||
|
||||
local pid
|
||||
pid="$(read_pid "$API_PID_FILE")"
|
||||
if is_pid_running "$pid"; then
|
||||
warn "API 已在运行 (PID: $pid)"
|
||||
return
|
||||
fi
|
||||
|
||||
export PYTHONPATH="backend${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
if [ "$mode" = "foreground" ]; then
|
||||
print_header "AI+合规智能中枢 - 启动 API"
|
||||
echo "运行模式: 前台调试(带 --reload)"
|
||||
echo "服务地址: http://localhost:$API_PORT"
|
||||
echo "文档地址: http://localhost:$API_PORT/docs"
|
||||
echo "健康检查: http://localhost:$API_PORT/health"
|
||||
echo ""
|
||||
exec "$VENV_PYTHON" -m uvicorn app.main:app --host "$API_HOST" --port "$API_PORT" --reload
|
||||
fi
|
||||
|
||||
nohup "$VENV_PYTHON" -m uvicorn app.main:app --host "$API_HOST" --port "$API_PORT" > "$API_LOG_FILE" 2>&1 &
|
||||
pid=$!
|
||||
echo "$pid" > "$API_PID_FILE"
|
||||
sleep 3
|
||||
|
||||
if is_pid_running "$pid"; then
|
||||
success "API 启动成功 (PID: $pid)"
|
||||
echo " 地址: http://localhost:$API_PORT"
|
||||
echo " 文档: http://localhost:$API_PORT/docs"
|
||||
echo " 日志: $API_LOG_FILE"
|
||||
else
|
||||
rm -f "$API_PID_FILE"
|
||||
die "API 启动失败,请查看日志: $API_LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
start_frontend() {
|
||||
local mode="${1:-$FRONTEND_MODE}"
|
||||
load_env
|
||||
ensure_log_dir
|
||||
cleanup_stale_pid "$FRONTEND_PID_FILE"
|
||||
|
||||
local pid
|
||||
pid="$(read_pid "$FRONTEND_PID_FILE")"
|
||||
if is_pid_running "$pid"; then
|
||||
warn "前端已在运行 (PID: $pid)"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! command -v npm > /dev/null 2>&1; then
|
||||
die "未找到 npm,请先安装 Node.js 20+。"
|
||||
fi
|
||||
|
||||
ensure_frontend_deps
|
||||
|
||||
if [ "$mode" = "static" ]; then
|
||||
require_python_bootstrap
|
||||
npm --prefix frontend run build
|
||||
nohup "$PYTHON_BOOTSTRAP" -m http.server "$FRONTEND_PORT" --bind 0.0.0.0 --directory frontend/dist > "$FRONTEND_LOG_FILE" 2>&1 &
|
||||
else
|
||||
nohup npm --prefix frontend run dev -- --host 0.0.0.0 --port "$FRONTEND_PORT" > "$FRONTEND_LOG_FILE" 2>&1 &
|
||||
fi
|
||||
|
||||
pid=$!
|
||||
echo "$pid" > "$FRONTEND_PID_FILE"
|
||||
sleep 4
|
||||
|
||||
if is_pid_running "$pid"; then
|
||||
success "前端启动成功 (PID: $pid)"
|
||||
echo " 地址: http://localhost:$FRONTEND_PORT"
|
||||
echo " 模式: $mode"
|
||||
echo " 日志: $FRONTEND_LOG_FILE"
|
||||
else
|
||||
rm -f "$FRONTEND_PID_FILE"
|
||||
die "前端启动失败,请查看日志: $FRONTEND_LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
kill_pid_file_process() {
|
||||
local pid_file="$1"
|
||||
local label="$2"
|
||||
local pid
|
||||
pid="$(read_pid "$pid_file")"
|
||||
|
||||
if ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
warn "$label 未通过 PID 文件发现运行中的进程"
|
||||
return 1
|
||||
fi
|
||||
|
||||
kill "$pid" 2>/dev/null || true
|
||||
sleep 2
|
||||
if is_pid_running "$pid"; then
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
success "$label 已停止"
|
||||
return 0
|
||||
}
|
||||
|
||||
stop_api() {
|
||||
load_env
|
||||
ensure_log_dir
|
||||
|
||||
if kill_pid_file_process "$API_PID_FILE" "API"; then
|
||||
return
|
||||
fi
|
||||
|
||||
local port_listener
|
||||
port_listener="$(port_pid "$API_PORT")"
|
||||
if [ -n "$port_listener" ]; then
|
||||
kill "$port_listener" 2>/dev/null || true
|
||||
sleep 1
|
||||
if is_pid_running "$port_listener"; then
|
||||
kill -9 "$port_listener" 2>/dev/null || true
|
||||
fi
|
||||
success "已停止监听 API 端口 $API_PORT 的进程 (PID: $port_listener)"
|
||||
else
|
||||
warn "未发现运行中的 API 服务"
|
||||
fi
|
||||
|
||||
rm -f "$API_PID_FILE"
|
||||
}
|
||||
|
||||
stop_frontend() {
|
||||
load_env
|
||||
ensure_log_dir
|
||||
|
||||
if kill_pid_file_process "$FRONTEND_PID_FILE" "前端"; then
|
||||
return
|
||||
fi
|
||||
|
||||
local port_listener
|
||||
port_listener="$(port_pid "$FRONTEND_PORT")"
|
||||
if [ -n "$port_listener" ]; then
|
||||
kill "$port_listener" 2>/dev/null || true
|
||||
sleep 1
|
||||
if is_pid_running "$port_listener"; then
|
||||
kill -9 "$port_listener" 2>/dev/null || true
|
||||
fi
|
||||
success "已停止监听前端端口 $FRONTEND_PORT 的进程 (PID: $port_listener)"
|
||||
else
|
||||
warn "未发现运行中的前端服务"
|
||||
fi
|
||||
|
||||
rm -f "$FRONTEND_PID_FILE"
|
||||
}
|
||||
|
||||
run_status() {
|
||||
load_env
|
||||
ensure_log_dir
|
||||
print_header "AI+合规智能中枢 - 服务状态"
|
||||
|
||||
cleanup_stale_pid "$API_PID_FILE"
|
||||
cleanup_stale_pid "$FRONTEND_PID_FILE"
|
||||
|
||||
local api_running=false
|
||||
local frontend_running=false
|
||||
local pid
|
||||
local port_listener
|
||||
|
||||
echo -e "${YELLOW}API 服务:${NC}"
|
||||
pid="$(read_pid "$API_PID_FILE")"
|
||||
if is_pid_running "$pid"; then
|
||||
api_running=true
|
||||
success " 状态: 运行中"
|
||||
echo " PID: $pid"
|
||||
else
|
||||
port_listener="$(port_pid "$API_PORT")"
|
||||
if [ -n "$port_listener" ]; then
|
||||
api_running=true
|
||||
success " 状态: 运行中 (无 PID 文件)"
|
||||
echo " PID: $port_listener"
|
||||
else
|
||||
error " 状态: 已停止"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$api_running" = true ]; then
|
||||
if api_health_ok; then
|
||||
success " 健康检查: 正常"
|
||||
else
|
||||
warn " 健康检查: 未通过"
|
||||
fi
|
||||
fi
|
||||
echo " 地址: http://localhost:$API_PORT"
|
||||
echo " 文档: http://localhost:${API_PORT}/docs"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}前端服务:${NC}"
|
||||
pid="$(read_pid "$FRONTEND_PID_FILE")"
|
||||
if is_pid_running "$pid"; then
|
||||
frontend_running=true
|
||||
success " 状态: 运行中"
|
||||
echo " PID: $pid"
|
||||
else
|
||||
port_listener="$(port_pid "$FRONTEND_PORT")"
|
||||
if [ -n "$port_listener" ]; then
|
||||
frontend_running=true
|
||||
success " 状态: 运行中 (无 PID 文件)"
|
||||
echo " PID: $port_listener"
|
||||
else
|
||||
error " 状态: 已停止"
|
||||
fi
|
||||
fi
|
||||
echo " 模式: $FRONTEND_MODE"
|
||||
echo " 地址: http://localhost:$FRONTEND_PORT"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Docker 服务:${NC}"
|
||||
if command -v docker > /dev/null 2>&1; then
|
||||
local container
|
||||
for container in $DOCKER_CONTAINERS; do
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
|
||||
success " ${container}: 运行中"
|
||||
elif docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
|
||||
warn " ${container}: 已停止"
|
||||
else
|
||||
warn " ${container}: 未创建"
|
||||
fi
|
||||
done
|
||||
else
|
||||
warn " Docker 未安装,已跳过"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ "$api_running" = true ] && [ "$frontend_running" = true ]; then
|
||||
success "所有核心服务均在运行"
|
||||
else
|
||||
warn "存在未运行的服务,可使用 ./dev.sh start 启动"
|
||||
fi
|
||||
}
|
||||
|
||||
run_logs() {
|
||||
local target="${1:-}"
|
||||
local follow="${2:-}"
|
||||
local log_file
|
||||
|
||||
case "$target" in
|
||||
api)
|
||||
log_file="$API_LOG_FILE"
|
||||
;;
|
||||
frontend)
|
||||
log_file="$FRONTEND_LOG_FILE"
|
||||
;;
|
||||
*)
|
||||
die "请指定日志类型: api 或 frontend"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -f "$log_file" ] || die "日志文件不存在: $log_file"
|
||||
|
||||
if [ "$follow" = "--follow" ]; then
|
||||
tail -f "$log_file"
|
||||
else
|
||||
tail -n 50 "$log_file"
|
||||
fi
|
||||
}
|
||||
|
||||
show_help() {
|
||||
cat <<'EOF'
|
||||
AI+合规智能中枢统一脚本
|
||||
|
||||
用法:
|
||||
./dev.sh help
|
||||
./dev.sh setup
|
||||
./dev.sh start [all|api|frontend] [--foreground] [--mode dev|static]
|
||||
./dev.sh stop [all|api|frontend]
|
||||
./dev.sh restart [all|api|frontend] [--mode dev|static]
|
||||
./dev.sh status
|
||||
./dev.sh logs <api|frontend> [--follow]
|
||||
|
||||
命令说明:
|
||||
help
|
||||
输出完整帮助信息、默认端口、日志目录和常见示例。
|
||||
|
||||
setup
|
||||
进行一次性的本地初始化。
|
||||
包含 Python 版本检查、.venv 虚拟环境创建、后端依赖安装、前端 npm install、
|
||||
以及 Docker 基础容器状态检查。
|
||||
|
||||
start
|
||||
启动服务。默认行为等同于 ./dev.sh start all。
|
||||
可选目标:
|
||||
all 同时启动 API 和前端。
|
||||
api 只启动后端 API。
|
||||
frontend 只启动前端。
|
||||
可选参数:
|
||||
--foreground 仅对 start api 生效,前台运行并开启 --reload,便于调试。
|
||||
--mode dev 前端使用 Vite 开发服务器,默认端口 5173。
|
||||
--mode static 前端先执行 npm run build,再以静态文件服务器方式启动。
|
||||
|
||||
stop
|
||||
停止服务。默认行为等同于 ./dev.sh stop all。
|
||||
会优先读取 logs/*.pid,PID 文件失效时会回退到端口探测。
|
||||
|
||||
restart
|
||||
先停止再启动,支持 all/api/frontend。
|
||||
restart frontend --mode static 可直接切换前端启动模式。
|
||||
|
||||
status
|
||||
查看 API、前端、Docker 基础容器的状态。
|
||||
API 状态包含健康检查;前端状态包含当前模式和访问地址。
|
||||
|
||||
logs
|
||||
查看日志。默认输出最后 50 行。
|
||||
追加 --follow 后会持续跟踪日志输出。
|
||||
|
||||
默认约定:
|
||||
API_HOST 默认 0.0.0.0
|
||||
API_PORT 默认 8000
|
||||
FRONTEND_PORT 默认 5173
|
||||
FRONTEND_MODE 默认 dev
|
||||
日志目录 logs/
|
||||
PID 文件 logs/api.pid, logs/frontend.pid
|
||||
|
||||
常用示例:
|
||||
./dev.sh setup
|
||||
./dev.sh start
|
||||
./dev.sh start api --foreground
|
||||
./dev.sh start frontend --mode static
|
||||
./dev.sh restart frontend --mode dev
|
||||
./dev.sh status
|
||||
./dev.sh logs api --follow
|
||||
./dev.sh logs frontend
|
||||
EOF
|
||||
}
|
||||
|
||||
parse_target() {
|
||||
local default_target="$1"
|
||||
local candidate="${2:-}"
|
||||
case "$candidate" in
|
||||
all|api|frontend)
|
||||
echo "$candidate"
|
||||
;;
|
||||
*)
|
||||
echo "$default_target"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
local command="${1:-help}"
|
||||
local target="all"
|
||||
local mode=""
|
||||
local foreground=false
|
||||
local log_target=""
|
||||
shift || true
|
||||
load_env
|
||||
|
||||
case "$command" in
|
||||
help|-h|--help)
|
||||
show_help
|
||||
;;
|
||||
setup)
|
||||
run_setup
|
||||
;;
|
||||
start)
|
||||
target="$(parse_target all "${1:-}")"
|
||||
if [ "$target" != "all" ]; then
|
||||
shift || true
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--foreground)
|
||||
foreground=true
|
||||
;;
|
||||
--mode)
|
||||
shift || die "--mode 需要指定 dev 或 static"
|
||||
mode="$1"
|
||||
validate_frontend_mode "$mode"
|
||||
;;
|
||||
*)
|
||||
die "未知参数: $1"
|
||||
;;
|
||||
esac
|
||||
shift || true
|
||||
done
|
||||
|
||||
case "$target" in
|
||||
all)
|
||||
[ "$foreground" = false ] || die "start all 不支持 --foreground,请使用 start api --foreground"
|
||||
print_header "AI+合规智能中枢 - 启动服务"
|
||||
start_api background
|
||||
start_frontend "${mode:-$FRONTEND_MODE}"
|
||||
;;
|
||||
api)
|
||||
if [ "$foreground" = true ]; then
|
||||
start_api foreground
|
||||
else
|
||||
print_header "AI+合规智能中枢 - 启动 API"
|
||||
start_api background
|
||||
fi
|
||||
;;
|
||||
frontend)
|
||||
print_header "AI+合规智能中枢 - 启动前端"
|
||||
start_frontend "${mode:-$FRONTEND_MODE}"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
target="$(parse_target all "${1:-}")"
|
||||
print_header "AI+合规智能中枢 - 停止服务"
|
||||
case "$target" in
|
||||
all)
|
||||
stop_frontend
|
||||
stop_api
|
||||
;;
|
||||
api)
|
||||
stop_api
|
||||
;;
|
||||
frontend)
|
||||
stop_frontend
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
restart)
|
||||
target="$(parse_target all "${1:-}")"
|
||||
if [ "$target" != "all" ]; then
|
||||
shift || true
|
||||
fi
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--mode)
|
||||
shift || die "--mode 需要指定 dev 或 static"
|
||||
mode="$1"
|
||||
validate_frontend_mode "$mode"
|
||||
;;
|
||||
*)
|
||||
die "未知参数: $1"
|
||||
;;
|
||||
esac
|
||||
shift || true
|
||||
done
|
||||
|
||||
print_header "AI+合规智能中枢 - 重启服务"
|
||||
case "$target" in
|
||||
all)
|
||||
stop_frontend
|
||||
stop_api
|
||||
start_api background
|
||||
start_frontend "${mode:-$FRONTEND_MODE}"
|
||||
;;
|
||||
api)
|
||||
stop_api
|
||||
start_api background
|
||||
;;
|
||||
frontend)
|
||||
stop_frontend
|
||||
start_frontend "${mode:-$FRONTEND_MODE}"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
run_status
|
||||
;;
|
||||
logs)
|
||||
log_target="${1:-}"
|
||||
run_logs "$log_target" "${2:-}"
|
||||
;;
|
||||
*)
|
||||
die "未知命令: $command。可使用 ./dev.sh help 查看帮助。"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user