144 lines
5.0 KiB
PowerShell
144 lines
5.0 KiB
PowerShell
#Requires -Version 5.1
|
||||
|
|
<#
|
|||
|
|
.SYNOPSIS
|
|||
|
|
重启本机 JinRong 前后端开发服务(前端 Vite · 后端 Docker 或本机 uvicorn)。
|
|||
|
|
.EXAMPLE
|
|||
|
|
.\scripts\dev\restart-dev.ps1
|
|||
|
|
.\scripts\dev\restart-dev.ps1 -Backend Local
|
|||
|
|
.\scripts\dev\restart-dev.ps1 -DockerContainer stu-system-app
|
|||
|
|
.NOTES
|
|||
|
|
后端 Auto:若 Docker 有容器映射 8000 → docker restart;否则停 8000 监听并新开窗口跑 uvicorn。
|
|||
|
|
前端:释放 5173–5175 后在新 PowerShell 窗口执行 npm run dev。
|
|||
|
|
Redis 不在此脚本内;需要时先 .\scripts\dev\start-redis.ps1
|
|||
|
|
#>
|
|||
|
|
param(
|
|||
|
|
[ValidateSet("Auto", "Docker", "Local")]
|
|||
|
|
[string]$Backend = "Auto",
|
|||
|
|
[string]$DockerContainer = "",
|
|||
|
|
[switch]$SkipBackend,
|
|||
|
|
[switch]$SkipFrontend
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
$ErrorActionPreference = "Stop"
|
|||
|
|
$Root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
|
|||
|
|
$Web = Join-Path $Root "web"
|
|||
|
|
Set-Location $Root
|
|||
|
|
|
|||
|
|
function Get-ListenerPids([int[]]$Ports) {
|
|||
|
|
$pids = @()
|
|||
|
|
foreach ($port in $Ports) {
|
|||
|
|
Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue |
|
|||
|
|
ForEach-Object { $pids += $_.OwningProcess }
|
|||
|
|
}
|
|||
|
|
$pids | Select-Object -Unique
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Stop-PortListeners([int[]]$Ports) {
|
|||
|
|
foreach ($procId in (Get-ListenerPids $Ports)) {
|
|||
|
|
if ($procId -and $procId -gt 0) {
|
|||
|
|
Stop-Process -Id $procId -Force -ErrorAction SilentlyContinue
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Get-DockerBackendName {
|
|||
|
|
if ($DockerContainer -ne "") {
|
|||
|
|
return $DockerContainer
|
|||
|
|
}
|
|||
|
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
|
|||
|
|
return $null
|
|||
|
|
}
|
|||
|
|
$name = docker ps --filter "publish=8000" --format "{{.Names}}" 2>$null | Select-Object -First 1
|
|||
|
|
if ($name) { return $name.Trim() }
|
|||
|
|
return $null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Test-HttpOk([string]$Url, [int]$TimeoutSec = 12) {
|
|||
|
|
try {
|
|||
|
|
$null = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec $TimeoutSec
|
|||
|
|
return $true
|
|||
|
|
} catch {
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Test-HealthOk {
|
|||
|
|
try {
|
|||
|
|
$r = Invoke-RestMethod -Uri "http://127.0.0.1:8000/health" -TimeoutSec 15
|
|||
|
|
return ($r.status -eq "ok")
|
|||
|
|
} catch {
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# --- 后端 -----------------------------------------------------------------
|
|||
|
|
if (-not $SkipBackend) {
|
|||
|
|
$useDocker = $false
|
|||
|
|
$container = Get-DockerBackendName
|
|||
|
|
|
|||
|
|
switch ($Backend) {
|
|||
|
|
"Docker" {
|
|||
|
|
if (-not $container) {
|
|||
|
|
Write-Error "未找到映射 8000 的 Docker 容器;请 -DockerContainer 指定或改用 -Backend Local"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
$useDocker = $true
|
|||
|
|
}
|
|||
|
|
"Local" { $useDocker = $false }
|
|||
|
|
default {
|
|||
|
|
$useDocker = [bool]$container
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($useDocker) {
|
|||
|
|
Write-Host "重启后端 Docker: $container (8000) ..." -ForegroundColor Cyan
|
|||
|
|
docker restart $container | Out-Null
|
|||
|
|
$deadline = (Get-Date).AddSeconds(45)
|
|||
|
|
while ((Get-Date) -lt $deadline) {
|
|||
|
|
if (Test-HealthOk) { break }
|
|||
|
|
Start-Sleep -Seconds 2
|
|||
|
|
}
|
|||
|
|
if (-not (Test-HealthOk)) {
|
|||
|
|
Write-Host "[WARN] /health 暂未就绪,请稍后 docker logs $container" -ForegroundColor Yellow
|
|||
|
|
} else {
|
|||
|
|
Write-Host "后端就绪: http://127.0.0.1:8000/health" -ForegroundColor Green
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if ($container) {
|
|||
|
|
Write-Host "[WARN] 检测到 Docker 容器 '$container' 仍占用 8000;Local 模式请先停容器或改用 -Backend Docker" -ForegroundColor Yellow
|
|||
|
|
}
|
|||
|
|
Write-Host "重启本机 uvicorn (8000) ..." -ForegroundColor Cyan
|
|||
|
|
Stop-PortListeners @(8000)
|
|||
|
|
Start-Sleep -Seconds 1
|
|||
|
|
$uvicornCmd = "Set-Location '$Root'; python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000"
|
|||
|
|
Start-Process powershell -ArgumentList @("-NoExit", "-Command", $uvicornCmd)
|
|||
|
|
Start-Sleep -Seconds 4
|
|||
|
|
if (Test-HealthOk) {
|
|||
|
|
Write-Host "后端就绪: http://127.0.0.1:8000/health" -ForegroundColor Green
|
|||
|
|
} else {
|
|||
|
|
Write-Host "[WARN] uvicorn 窗口已打开,/health 尚未响应(可能仍在启动)" -ForegroundColor Yellow
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# --- 前端 -----------------------------------------------------------------
|
|||
|
|
if (-not $SkipFrontend) {
|
|||
|
|
if (-not (Test-Path (Join-Path $Web "package.json"))) {
|
|||
|
|
Write-Error "未找到 web/package.json"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
Write-Host "重启前端 Vite (5173) ..." -ForegroundColor Cyan
|
|||
|
|
Stop-PortListeners @(5173, 5174, 5175)
|
|||
|
|
Start-Sleep -Seconds 1
|
|||
|
|
$viteCmd = "Set-Location '$Web'; npm run dev"
|
|||
|
|
Start-Process powershell -ArgumentList @("-NoExit", "-Command", $viteCmd)
|
|||
|
|
Start-Sleep -Seconds 4
|
|||
|
|
if (Test-HttpOk "http://localhost:5173/") {
|
|||
|
|
Write-Host "前端就绪: http://localhost:5173/" -ForegroundColor Green
|
|||
|
|
} else {
|
|||
|
|
Write-Host "[WARN] Vite 窗口已打开,5173 暂未响应(可能落在 5174,请看新窗口日志)" -ForegroundColor Yellow
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Host "`n完成。后端 Swagger: http://127.0.0.1:8000/docs" -ForegroundColor DarkGray
|