feat(portal-shell): v2.0 P0 shadcn standardization + security + streaming + error handling

- 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 路由生成成功
This commit is contained in:
SpecialX
2026-07-17 16:10:05 +08:00
parent f7e52b5b7f
commit 9cedf0c437
140 changed files with 10872 additions and 3192 deletions

View File

@@ -1,33 +1,61 @@
<#
.SYNOPSIS
Edu stop all application services script
Edu v2.1 一键关闭脚本
.DESCRIPTION
Closes all edu-app-* terminal windows (started by start-all.ps1)
Optional: kill processes by port (fallback when windows are closed but processes linger)
关闭顺序:
1. 关闭 Apollo Router Docker 容器(避免子图关闭时 router 报错)
2. 关闭应用服务窗口edu-app-* 标题匹配)
3. 按端口杀残留进程(可选 -KillByPort
4. 关闭 Docker 基础设施(可选 -IncludeDocker
.PARAMETER KillByPort
Kill processes by port (fallback when windows are closed but processes still alive)
按端口强制杀进程(窗口关闭后进程残留时使用)
.PARAMETER IncludeDocker
同时关闭 Docker 基础设施容器
.PARAMETER SkipRouter
跳过 Apollo Router 容器关闭
.EXAMPLE
.\scripts\stop-all.ps1
.\scripts\stop-all.ps1 -KillByPort
.\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]$KillByPort,
[switch]$IncludeDocker,
[switch]$SkipRouter
)
$ErrorActionPreference = "Continue"
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " Edu Stop All Services" -ForegroundColor Cyan
Write-Host " Edu v2.1 Stop All Services" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# ===== 1. Close app service terminal windows =====
Write-Host "[1/2] Closing app service windows..." -ForegroundColor Yellow
# ===== 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-classes",
"edu-app-iam",
"edu-app-teacher-bff",
"edu-app-config-service",
"edu-app-classes",
"edu-app-core-edu",
"edu-app-content",
"edu-app-msg",
@@ -35,14 +63,13 @@ $appTitles = @(
"edu-app-ai",
"edu-app-api-gateway",
"edu-app-push-gateway",
"edu-app-teacher-portal"
"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 {
@@ -57,17 +84,14 @@ foreach ($title in $appTitles) {
Write-Host " [--] $title window not found" -ForegroundColor Gray
}
}
Write-Host ""
Write-Host " Closed $closedCount windows" -ForegroundColor Green
Write-Host ""
# ===== 2. Kill by port (optional) =====
# ===== 2. 按端口杀残留进程 =====
if ($KillByPort) {
Write-Host "[2/2] Killing processes by port..." -ForegroundColor Yellow
$ports = @(3000,3001,3002,3003,3004,3005,3006,3007,3008,8080,8081)
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) {
@@ -85,14 +109,35 @@ if ($KillByPort) {
}
}
} else {
Write-Host "[2/2] Skipping port kill (use -KillByPort to enable)" -ForegroundColor Gray
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
Write-Host ""
Write-Host "To stop infrastructure:" -ForegroundColor Yellow
Write-Host " docker compose -f infra/docker-compose.yml --profile p6 --profile observability down" -ForegroundColor White
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 ""