- shadcn/ui 标准化:废弃纸感令牌,统一 bg-background/text-foreground 等 - Tailwind v4 + @theme inline,移除 tailwind.config.js - React 19 use() + Suspense 流式渲染,首屏骨架秒出 - 三级错误边界:Route → Section → Widget 层层兜底 - 错误上报:useErrorReport → sendBeacon → /api/log mock 端点 - 三层安全边界:L1 角色门禁 / L2 权限点门禁 / L3 数据范围 - 权限位图 base36 压缩:67 权限点 → ~14 字符,JWT 体积减少 ≥ 99% - notify 统一 Toast 封装,禁止业务直接 import sonner - PluginBoundary 替代 PluginLoader(错误边界 + Suspense + Skeleton 三件套) 验证:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功
144 lines
5.5 KiB
PowerShell
144 lines
5.5 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
Edu v2.1 一键关闭脚本
|
||
.DESCRIPTION
|
||
关闭顺序:
|
||
1. 关闭 Apollo Router Docker 容器(避免子图关闭时 router 报错)
|
||
2. 关闭应用服务窗口(edu-app-* 标题匹配)
|
||
3. 按端口杀残留进程(可选 -KillByPort)
|
||
4. 关闭 Docker 基础设施(可选 -IncludeDocker)
|
||
.PARAMETER KillByPort
|
||
按端口强制杀进程(窗口关闭后进程残留时使用)
|
||
.PARAMETER IncludeDocker
|
||
同时关闭 Docker 基础设施容器
|
||
.PARAMETER SkipRouter
|
||
跳过 Apollo Router 容器关闭
|
||
.EXAMPLE
|
||
.\scripts\stop-all.ps1 # 关闭应用服务 + Router
|
||
.\scripts\stop-all.ps1 -KillByPort # 强制杀端口进程
|
||
.\scripts\stop-all.ps1 -IncludeDocker # 关闭应用 + Router + Docker
|
||
.\scripts\stop-all.ps1 -KillByPort -IncludeDocker # 全部关闭
|
||
#>
|
||
param(
|
||
[switch]$KillByPort,
|
||
[switch]$IncludeDocker,
|
||
[switch]$SkipRouter
|
||
)
|
||
|
||
$ErrorActionPreference = "Continue"
|
||
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host " Edu v2.1 Stop All Services" -ForegroundColor Cyan
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# ===== 0. 关闭 Apollo Router 容器 =====
|
||
# 先关闭 router,避免子图关闭时 router 报连接错误刷日志
|
||
if (-not $SkipRouter) {
|
||
Write-Host "[0/3] Stopping Apollo Router container..." -ForegroundColor Yellow
|
||
$routerRunning = docker inspect -f '{{.State.Running}}' edu-apollo-router 2>$null
|
||
if ($routerRunning -eq "true") {
|
||
docker rm -f edu-apollo-router 2>&1 | Out-Null
|
||
Write-Host " [OK] edu-apollo-router removed" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " [--] edu-apollo-router not running" -ForegroundColor Gray
|
||
}
|
||
Write-Host ""
|
||
} else {
|
||
Write-Host "[0/3] Skipping Apollo Router (-SkipRouter)" -ForegroundColor Gray
|
||
Write-Host ""
|
||
}
|
||
|
||
# ===== 1. 关闭应用服务窗口 =====
|
||
Write-Host "[1/3] Closing app service windows..." -ForegroundColor Yellow
|
||
|
||
$appTitles = @(
|
||
"edu-app-iam",
|
||
"edu-app-config-service",
|
||
"edu-app-classes",
|
||
"edu-app-core-edu",
|
||
"edu-app-content",
|
||
"edu-app-msg",
|
||
"edu-app-data-ana",
|
||
"edu-app-ai",
|
||
"edu-app-api-gateway",
|
||
"edu-app-push-gateway",
|
||
"edu-app-portal-shell"
|
||
)
|
||
|
||
$closedCount = 0
|
||
foreach ($title in $appTitles) {
|
||
$procs = Get-Process -Name "powershell","pwsh","node","python","uvicorn","go" -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.MainWindowTitle -like "*$title*" }
|
||
if ($procs) {
|
||
foreach ($p in $procs) {
|
||
try {
|
||
Stop-Process -Id $p.Id -Force -ErrorAction Stop
|
||
Write-Host " [OK] Closed $title (PID $($p.Id))" -ForegroundColor Green
|
||
$closedCount++
|
||
} catch {
|
||
Write-Host " [WARN] Cannot close $title (PID $($p.Id)): $($_.Exception.Message)" -ForegroundColor Yellow
|
||
}
|
||
}
|
||
} else {
|
||
Write-Host " [--] $title window not found" -ForegroundColor Gray
|
||
}
|
||
}
|
||
Write-Host ""
|
||
Write-Host " Closed $closedCount windows" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ===== 2. 按端口杀残留进程 =====
|
||
if ($KillByPort) {
|
||
Write-Host "[2/3] Killing processes by port..." -ForegroundColor Yellow
|
||
$ports = @(3000,3001,3002,3004,3005,3006,3007,3008,3011,8080,8081,4010,50052,50053,50054,50055,50056,50058,50059)
|
||
foreach ($port in $ports) {
|
||
$connections = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
|
||
if ($connections) {
|
||
foreach ($conn in $connections) {
|
||
try {
|
||
$proc = Get-Process -Id $conn.OwningProcess -ErrorAction Stop
|
||
Stop-Process -Id $conn.OwningProcess -Force -ErrorAction Stop
|
||
Write-Host " [OK] Port $port -> killed $($proc.ProcessName) (PID $($conn.OwningProcess))" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host " [WARN] Port $port -> cannot kill PID $($conn.OwningProcess)" -ForegroundColor Yellow
|
||
}
|
||
}
|
||
} else {
|
||
Write-Host " [--] Port $port free" -ForegroundColor Gray
|
||
}
|
||
}
|
||
} else {
|
||
Write-Host "[2/3] Skipping port kill (use -KillByPort to enable)" -ForegroundColor Gray
|
||
}
|
||
Write-Host ""
|
||
|
||
# ===== 3. 关闭 Docker 基础设施 =====
|
||
if ($IncludeDocker) {
|
||
Write-Host "[3/3] Stopping Docker infrastructure..." -ForegroundColor Yellow
|
||
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
||
Push-Location "$ProjectRoot\infra"
|
||
try {
|
||
# 停止所有 profile 的所有容器(包括可能存在的 app 容器)
|
||
docker compose -f docker-compose.yml --profile p3 --profile p5 --profile observability down 2>&1 | Out-Host
|
||
Write-Host " [OK] Docker containers stopped" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host " [WARN] $_" -ForegroundColor Yellow
|
||
}
|
||
Pop-Location
|
||
} else {
|
||
Write-Host "[3/3] Skipping Docker (-IncludeDocker to enable)" -ForegroundColor Gray
|
||
}
|
||
Write-Host ""
|
||
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host " Stop complete" -ForegroundColor Cyan
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
if (-not $IncludeDocker) {
|
||
Write-Host ""
|
||
Write-Host "To stop Docker infrastructure:" -ForegroundColor Yellow
|
||
Write-Host " .\scripts\stop-all.ps1 -IncludeDocker" -ForegroundColor White
|
||
Write-Host " or: docker compose -f infra/docker-compose.yml --profile p6 --profile observability down" -ForegroundColor White
|
||
}
|
||
Write-Host ""
|