# 优化的部署脚本 - 使用 Docker 构建缓存和最佳实践 param( [string]$Server = "45.249.208.118", [string]$User = "root", [string]$Password = "lxvhNYFZ4160", [string]$ProjectPath = "/root/youyidian-3d", [switch]$NoCache = $false # 默认使用缓存,除非明确指定 --NoCache ) $ErrorActionPreference = "Stop" Write-Host "========================================" -ForegroundColor Cyan Write-Host " 优化部署脚本 - 使用构建缓存" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" # 检查工具 $plinkPath = "C:\Program Files\PuTTY\plink.exe" $pscpPath = "C:\Program Files\PuTTY\pscp.exe" if (-not (Test-Path $plinkPath)) { Write-Host "错误: 未找到 plink.exe,请安装 PuTTY" -ForegroundColor Red exit 1 } if (-not (Test-Path $pscpPath)) { Write-Host "错误: 未找到 pscp.exe,请安装 PuTTY" -ForegroundColor Red exit 1 } # 步骤 1: 准备要上传的文件 Write-Host "[1/5] 准备部署文件..." -ForegroundColor Yellow # 需要上传的关键文件(根据终端选择的内容) $filesToUpload = @( "app/page.tsx", "app/login/page.tsx", "app/api/network-status/route.ts", "app/api/admin/users/route.ts", # 用户管理API(修复isSuperAdmin字段) "app/api/admin/users/update/route.ts", # 用户更新API(添加权限检查) "app/api/admin/users/toggle-active/route.ts", # 用户激活API(添加权限检查) "app/api/admin/users/set-role/route.ts", # 用户角色设置API(添加权限检查) "app/api/admin/users/set-department-manager/route.ts", # 部门管理员设置API(同步更新department字段) "app/api/admin/users/update-hierarchy/route.ts", # 新的组织结构上下级更新接口 "app/api/admin/transfer-superadmin/route.ts", # 转移最高权限API(添加密码验证) "app/api/admin/upload-templates/route.ts", # 上传模板列表/创建 "app/api/admin/upload-templates/[id]/route.ts", # 上传模板详情/更新/删除 "app/api/ai/edit/route.ts", # AI改图占位API "app/api/tunnel/start/route.ts", # 内网穿透启动占位API "app/api/tunnel/stop/route.ts", # 内网穿透停止占位API "app/api/tunnel/status/route.ts", # 内网穿透状态占位API "app/api/system-settings/route.ts", # 系统设置接口(新增功能开关) "app/admin/page.tsx", # 用户管理页面(修复树形结构、权限显示、添加密码验证模态框) "app/admin/_components/TemplateManager.tsx", # 模板管理子组件 "app/admin/settings/page.tsx", # 设置页面(新增AI/内网穿透开关) "app/share/[id]/page.tsx", # 素材分享页(AI改图按钮占位) "components/Header.tsx", # Header组件(修复退出登录跳转) "lib/auth.ts", # NextAuth配置(清理配置) "prisma/schema.prisma", # Prisma schema文件(包含isSuperAdmin字段) "next.config.js", "README.md", "lib/config.ts", "lib/configLoader.ts", "config-bianliang.env", "Dockerfile", # 更新后的 Dockerfile "docker-compose.yml", "package.json", "package-lock.json" ) # 检查文件是否存在 $missingFiles = @() foreach ($file in $filesToUpload) { if (-not (Test-Path -LiteralPath $file)) { $missingFiles += $file } } if ($missingFiles.Count -gt 0) { Write-Host "警告: 以下文件不存在,将跳过:" -ForegroundColor Yellow $missingFiles | ForEach-Object { Write-Host " - $_" -ForegroundColor Yellow } } # 步骤 2: 上传文件 Write-Host "[2/5] 上传文件到服务器..." -ForegroundColor Yellow $uploadedCount = 0 foreach ($file in $filesToUpload) { if (Test-Path -LiteralPath $file) { $localFile = Get-Item -LiteralPath $file $remotePath = "$ProjectPath/$file" $remoteDir = ($remotePath -replace "/[^/]+$", "") # 确保远程目录存在 & $plinkPath -ssh -pw $Password -batch "${User}@${Server}" "mkdir -p `"$remoteDir`"" | Out-Null # 上传文件 $remoteTarget = "${User}@${Server}:`"$remotePath`"" & $pscpPath -pw $Password -batch -q $localFile.FullName $remoteTarget 2>&1 | Out-Null if ($LASTEXITCODE -eq 0) { $uploadedCount++ Write-Host " ✓ $file" -ForegroundColor Green } else { Write-Host " ✗ $file (上传失败)" -ForegroundColor Red } } } Write-Host "已上传 $uploadedCount/$($filesToUpload.Count) 个文件" -ForegroundColor $(if ($uploadedCount -eq $filesToUpload.Count) { "Green" } else { "Yellow" }) # 步骤 3: 创建优化的部署脚本 Write-Host "[3/5] 创建部署脚本..." -ForegroundColor Yellow $buildFlag = "" if ($NoCache) { $buildFlag = "--no-cache" } $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" Write-Host " ➤ 本地时间戳: $timestamp" -ForegroundColor DarkGray # 创建本地部署脚本文件 $localDeployScript = Join-Path $env:TEMP "deploy-optimized-$timestamp.sh" # 读取模板文件并替换占位符 $templateFile = Join-Path $PSScriptRoot "deploy-remote-template.sh" if (-not (Test-Path $templateFile)) { Write-Host "错误: 模板文件不存在: $templateFile" -ForegroundColor Red exit 1 } # 从模板文件读取(使用 -Raw 参数获取完整内容,包括换行符) $bashScriptContent = Get-Content -Path $templateFile -Raw # 替换占位符 $bashScriptContent = $bashScriptContent -replace "PROJECT_PATH_PLACEHOLDER", $ProjectPath if ($buildFlag) { $bashScriptContent = $bashScriptContent -replace "BUILD_FLAG_PLACEHOLDER", "BUILD_FLAG=`"$buildFlag`"" } else { $bashScriptContent = $bashScriptContent -replace "BUILD_FLAG_PLACEHOLDER", "BUILD_FLAG=" } # 写入文件 $utf8NoBom = New-Object System.Text.UTF8Encoding $false [System.IO.File]::WriteAllText($localDeployScript, $bashScriptContent, $utf8NoBom) # 步骤 4: 上传部署脚本 Write-Host "[4/5] 上传部署脚本..." -ForegroundColor Yellow $remoteDeployScript = "/tmp/deploy-optimized-$timestamp.sh" Write-Host " ➤ 远程脚本路径: $remoteDeployScript" -ForegroundColor DarkGray & $pscpPath -pw $Password -batch $localDeployScript "${User}@${Server}:$remoteDeployScript" if ($LASTEXITCODE -ne 0) { Write-Host "上传部署脚本失败" -ForegroundColor Red exit 1 } Write-Host " ✓ 部署脚本已上传" -ForegroundColor Green # 步骤 5: 执行部署 Write-Host "[5/5] 执行部署..." -ForegroundColor Yellow Write-Host "" & $plinkPath -ssh -pw $Password -batch "${User}@${Server}" "chmod +x $remoteDeployScript; bash $remoteDeployScript; rm -f $remoteDeployScript" $deployExitCode = $LASTEXITCODE # 清理本地临时文件 Remove-Item $localDeployScript -Force -ErrorAction SilentlyContinue if ($deployExitCode -ne 0) { Write-Host "" Write-Host "部署失败,退出码: $deployExitCode" -ForegroundColor Red exit 1 } Write-Host "" Write-Host "========================================" -ForegroundColor Green Write-Host " 部署成功完成!" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "" Write-Host "提示:" -ForegroundColor Yellow Write-Host " - 使用 --NoCache 参数可以强制重新构建(不使用缓存)" -ForegroundColor Gray Write-Host " - 默认使用构建缓存,可以大幅加速部署" -ForegroundColor Gray Write-Host " - 使用 -Password 参数可以指定不同的密码" -ForegroundColor Gray Write-Host ""