微信小程序页面迁移校验之前 P5任务处理之前

This commit is contained in:
Neo
2026-03-09 01:19:21 +08:00
parent 263bf96035
commit 6e20987d2f
1112 changed files with 153824 additions and 219694 deletions

View File

@@ -5,18 +5,35 @@
$ErrorActionPreference = "Stop"
try {
# 定位项目根目录:脚本在 scripts/ops/ 下,向上三级
if ($MyInvocation.MyCommand.Path) {
# CHANGE 2026-03-07 | 定位项目根目录:从 bat 启动目录推算,不穿透 junction
# 背景C:\NeoZQYY 是 junction → D:\NeoZQYY\...\repo
# $MyInvocation.MyCommand.Path 和 Split-Path 都会穿透 junction 解析到 D 盘,
# 导致后端 CWD、.venv python、.env 全部指向 D 盘副本。
# 解决:优先用环境变量 NEOZQYY_ROOT其次用 bat 传入的 %~dp0不穿透 junction
# 最后才回退到脚本路径推算。
if ($env:NEOZQYY_ROOT -and (Test-Path $env:NEOZQYY_ROOT)) {
$ProjectRoot = $env:NEOZQYY_ROOT
} elseif ($env:NEOZQYY_LAUNCH_DIR -and (Test-Path $env:NEOZQYY_LAUNCH_DIR)) {
# 由 start-admin.bat 通过 %~dp0 注入,不穿透 junction
$ProjectRoot = $env:NEOZQYY_LAUNCH_DIR.TrimEnd('\')
} elseif ($MyInvocation.MyCommand.Path) {
$ProjectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path))
} else {
$ProjectRoot = $PWD.Path
}
# CHANGE 2026-03-07 | 将 ProjectRoot 注入环境变量 NEOZQYY_ROOT
# 使 config.py 的 _find_project_root() 策略 1 直接命中,
# 不再依赖 __file__ 推算__file__ 会穿透 junction 到 D 盘)。
# 这个环境变量会被子进程uvicorn继承。
$env:NEOZQYY_ROOT = $ProjectRoot
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " NeoZQYY 管理后台启动脚本" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "项目根目录: $ProjectRoot"
Write-Host "NEOZQYY_ROOT=$env:NEOZQYY_ROOT"
Write-Host ""
$backendDir = Join-Path $ProjectRoot "apps\backend"
@@ -24,6 +41,65 @@ try {
if (-not (Test-Path $backendDir)) { throw "后端目录不存在: $backendDir" }
if (-not (Test-Path $frontendDir)) { throw "前端目录不存在: $frontendDir" }
# ── 端口冲突检测:确保 8000/5173 未被旧进程占用 ──
foreach ($port in @(8000, 5173)) {
$listeners = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
if ($listeners) {
foreach ($l in $listeners) {
$pid = $l.OwningProcess
$proc = Get-Process -Id $pid -ErrorAction SilentlyContinue
$procPath = if ($proc) { $proc.Path } else { "未知" }
Write-Host "端口 $port 被占用: PID=$pid ($procPath)" -ForegroundColor Yellow
# 尝试多种方式终止Stop-Process → taskkill /T /F
Write-Host " 正在终止旧进程..." -ForegroundColor Yellow
Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
# 如果 Stop-Process 不够,用 taskkill 连子进程一起杀
# taskkill 非零退出码不应终止脚本
$ErrorActionPreference = "Continue"
taskkill /PID $pid /T /F 2>$null | Out-Null
$ErrorActionPreference = "Stop"
}
# 等待端口释放(最多 30 秒)
$waitMax = 30
$waited = 0
while ($waited -lt $waitMax) {
Start-Sleep -Seconds 2
$waited += 2
$still = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
if (-not $still) {
Write-Host " 端口 $port 已释放(等待 ${waited}s" -ForegroundColor Green
break
}
# 父进程可能已死但子进程仍占端口,扫描并杀子进程
$zombiePid = $still.OwningProcess
$children = Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $zombiePid }
if ($children) {
foreach ($child in $children) {
Write-Host " 发现残留子进程: PID=$($child.ProcessId) ($($child.ExecutablePath))" -ForegroundColor Yellow
# taskkill 非零退出码不应终止脚本
$ErrorActionPreference = "Continue"
taskkill /PID $child.ProcessId /T /F 2>$null | Out-Null
$ErrorActionPreference = "Stop"
}
}
Write-Host " 端口 $port 仍被占用,继续等待... (${waited}/${waitMax}s)" -ForegroundColor Yellow
}
if ($waited -ge $waitMax) {
$still2 = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
if ($still2) {
Write-Host ""
Write-Host " !! 端口 $port 无法释放(僵尸进程 PID=$($still2.OwningProcess)" -ForegroundColor Red
Write-Host " !! 请重启电脑或手动执行: netsh int ipv4 reset" -ForegroundColor Red
Write-Host " !! 或等待几分钟后重试" -ForegroundColor Red
throw "端口 $port 被僵尸进程占用,无法启动"
}
}
}
}
# 前端日志文件(每次用唯一文件名,避免上次进程锁定旧文件)
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$frontendLog = Join-Path $env:TEMP "neozqyy_fe_${ts}.log"
@@ -31,15 +107,39 @@ try {
# 选择 PowerShell 可执行文件:优先 pwsh (7+),回退 powershell (5.1)
$psExe = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
# ── 生成临时启动脚本 ──
$beTmp = Join-Path $env:TEMP "neozqyy_start_be.ps1"
$feTmp = Join-Path $env:TEMP "neozqyy_start_fe.ps1"
# ── 生成临时启动脚本(带时间戳,避免旧脚本残留) ──
$beTmp = Join-Path $env:TEMP "neozqyy_start_be_${ts}.ps1"
$feTmp = Join-Path $env:TEMP "neozqyy_start_fe_${ts}.ps1"
$q = [char]39
# CHANGE 2026-03-07 | 显式使用 .venv 的 python避免 uv run 解析到 miniconda
# 背景uv run uvicorn 在此机器上解析到 C:\ProgramData\miniconda3\python.exe
# 导致 config.py 的 Path(__file__).resolve() 指向错误的代码副本D 盘)
$venvPython = Join-Path $ProjectRoot ".venv\Scripts\python.exe"
if (-not (Test-Path $venvPython)) {
throw ".venv Python 不存在: $venvPython — 请先运行 uv sync"
}
# CHANGE 2026-03-07 | 临时脚本中显式注入 NEOZQYY_ROOT确保 uvicorn 子进程
# 无论通过何种方式启动都能拿到正确的项目根目录
# CHANGE 2026-03-07 | 解决 ANSI 转义码乱码:
# PowerShell 5.1 + 旧版 conhost 不解析 ANSI 转义序列uvicorn 彩色日志
# 显示为 [32m、[0m 等乱码。设置 NO_COLOR=1 禁用颜色输出。
# pwsh 7+ 和 Windows Terminal 原生支持 VT不受影响。
@(
"`$env:NEOZQYY_ROOT = ${q}${ProjectRoot}${q}"
""
"# pwsh 7+ 原生支持 ANSIPS 5.1 需要 Windows Terminal 才行"
"# 简单判断PSVersion.Major < 7 且不在 Windows Terminal 中 → 禁用颜色"
"if (`$PSVersionTable.PSVersion.Major -lt 7 -and -not `$env:WT_SESSION) {"
" `$env:NO_COLOR = ${q}1${q}"
" Write-Host ${q}[提示] PS 5.1 + 传统控制台,已禁用 ANSI 颜色${q} -ForegroundColor Yellow"
"}"
""
"Set-Location -LiteralPath ${q}${backendDir}${q}"
"Write-Host ${q}=== 后端 FastAPI ===${q} -ForegroundColor Green"
"uv run uvicorn app.main:app --reload --port 8000"
"Write-Host ${q}NEOZQYY_ROOT=`$env:NEOZQYY_ROOT${q}"
"& ${q}${venvPython}${q} -m uvicorn app.main:app --reload --port 8000"
"Write-Host ${q}后端已退出,按任意键关闭...${q} -ForegroundColor Red"
"`$null = `$Host.UI.RawUI.ReadKey(${q}NoEcho,IncludeKeyDown${q})"
) | Set-Content -Path $beTmp -Encoding UTF8