pack-deploy.ps1
@@ -3,13 +3,16 @@
  用法:
    powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1
    powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1 -OutRoot "E:\试验" -SkipFrontend
    powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1 -NoFrontendDist -SkipServiceWrapper
      —— 单端口发布:不生成独立的 frontend\dist 目录(仍构建并同步 backend\web,单端口必需);
         服务器已装服务时配合 -SkipServiceWrapper 去掉约 17 MB 的 WinSW,可显著减小包体积。
  做五件事:
    1) 用 deploy-templates\jar-application.yml(全占位符)临时替换源码 application.yml,
       执行 mvn clean package;无论成败都还原开发机真实配置
    2) 解压 jar 检查内置 application.yml:必须全是占位符(禁止 sk- 密钥 / 明文口令),不合格直接中止
    3) npm run build 重建前端 dist(可 -SkipFrontend)
    4) 组装完整部署包:backend(jar + application.yml + 启动脚本 + 服务包装器 + docs + web) / frontend/dist / db / README
    4) 组装完整部署包:backend(jar + application.yml + 启动脚本 + 服务包装器 + docs + web) / frontend/dist(可选,-NoFrontendDist 不打) / db / README
       Windows 服务包装器 WinSW:优先用 deploy-templates\tools\winsw.exe 缓存(校验 SHA-256),
       缺失时自动下载 v2.12.0 x64 到该缓存目录;随包输出为 backend\trafficAudit.exe
    5) 对组装后的整包再扫一遍明文密钥
@@ -22,6 +25,7 @@
param(
  [string]$OutRoot = '',
  [switch]$SkipFrontend,
  [switch]$NoFrontendDist,  # 单端口发布:不打独立的 frontend\dist 目录,但仍构建/同步 backend\web(单端口必需)
  [switch]$SkipBackend,     # 复用已存在的 jar(不重编译、不动源码配置),仅用于补全/重组发布包
  [switch]$SkipServiceWrapper   # 不把 WinSW 服务包装器打进包(即不提供“注册成 Windows 服务”的开机自启)
)
@@ -106,6 +110,7 @@
Write-Host '      通过:jar 内置配置全部为占位符,无明文密钥/口令。'
# ---------- [3/5] 前端构建 ----------
# 单端口部署必须有 backend\web,所以即使 -NoFrontendDist 也需要 dist;只有 -SkipFrontend 才复用现有 dist。
Write-Host '[3/5] 构建前端(npm run build,可 -SkipFrontend 跳过)...'
if (-not $SkipFrontend) {
  Push-Location (Join-Path $root 'traffic-audit-web')
@@ -160,7 +165,11 @@
$dest = Join-Path $OutRoot ("traffic-audit-deploy-" + $stamp)
$n = 2
while (Test-Path $dest) { $dest = Join-Path $OutRoot ("traffic-audit-deploy-" + $stamp + "-" + $n); $n++ }
New-Item -ItemType Directory -Force -Path (Join-Path $dest 'backend'), (Join-Path $dest 'frontend'), (Join-Path $dest 'db') | Out-Null
if ($NoFrontendDist) {
  New-Item -ItemType Directory -Force -Path (Join-Path $dest 'backend'), (Join-Path $dest 'db') | Out-Null
} else {
  New-Item -ItemType Directory -Force -Path (Join-Path $dest 'backend'), (Join-Path $dest 'frontend'), (Join-Path $dest 'db') | Out-Null
}
Copy-Item $jar (Join-Path $dest 'backend') -Force
Copy-Item (Join-Path $tplDir 'backend\application.yml') (Join-Path $dest 'backend') -Force
@@ -173,12 +182,16 @@
  Copy-Item -LiteralPath $winswSrc (Join-Path $dest 'backend\trafficAudit.exe') -Force
  Copy-Item (Join-Path $tplDir 'backend\trafficAudit.xml') (Join-Path $dest 'backend') -Force
  Copy-Item (Join-Path $tplDir 'backend\install-service.ps1') (Join-Path $dest 'backend') -Force
  Copy-Item (Join-Path $tplDir 'backend\install-service.cmd') (Join-Path $dest 'backend') -Force
}
Copy-Item $webDist (Join-Path $dest 'frontend') -Recurse -Force
Copy-Item (Join-Path $tplDir 'frontend\nginx.conf.example') (Join-Path $dest 'frontend') -Force
if (-not $NoFrontendDist) {
  Copy-Item $webDist (Join-Path $dest 'frontend') -Recurse -Force
  Copy-Item (Join-Path $tplDir 'frontend\nginx.conf.example') (Join-Path $dest 'frontend') -Force
}
Copy-Item (Join-Path $tplDir 'db\*.sql') (Join-Path $dest 'db') -Force
# 单端口 8090 模式:后端从 jar 同级 web\ 读前端静态文件,必须和 dist 内容一致
# 单端口 8090 模式:后端从 jar 同级 web\ 读前端静态文件,必须和 dist 内容一致。
# 单端口发布(-NoFrontendDist)同样必须同步,否则页面 404。
Copy-Item $webDist (Join-Path $dest 'backend\web') -Recurse -Force
# docs:运行时模板 + 用户文档;排除开发过程文档与缓存/备份(减小体积、避免把内部清单带出去)
@@ -187,7 +200,7 @@
cmd /c "robocopy `"$root\docs`" `"$docsDest`" /E /NFL /NDL /NJH /NJS /NP /XD _cache 工作日结 功能测试报告 问题汇总 /XF 生成_*.xlsx _bak_* >nul"
if ($LASTEXITCODE -ge 8) { throw "docs 复制失败(robocopy 返回 $LASTEXITCODE)" }
# db 脚本也放一份到 docs(与旧包一致:docs/init.sql 等)
Copy-Item (Join-Path $tplDir 'db\init.sql'), (Join-Path $tplDir 'db\sql_city_bus.sql'), (Join-Path $tplDir 'db\sql_city_taxi.sql'), (Join-Path $tplDir 'db\sql_wyc.sql'), (Join-Path $tplDir 'db\sql_holiday.sql'), (Join-Path $tplDir 'db\sql_holiday_decimal_migration.sql'), (Join-Path $tplDir 'db\sql_holiday_comparison_base_migration.sql') $docsDest -Force -ErrorAction SilentlyContinue
Copy-Item (Join-Path $tplDir 'db\init.sql'), (Join-Path $tplDir 'db\sql_city_bus.sql'), (Join-Path $tplDir 'db\sql_city_taxi.sql'), (Join-Path $tplDir 'db\sql_wyc.sql'), (Join-Path $tplDir 'db\sql_holiday.sql'), (Join-Path $tplDir 'db\sql_holiday_decimal_migration.sql'), (Join-Path $tplDir 'db\sql_holiday_comparison_base_migration.sql'), (Join-Path $tplDir 'db\sql_holiday_previous_day_migration.sql'), (Join-Path $tplDir 'db\sql_observation_station.sql') $docsDest -Force -ErrorAction SilentlyContinue
# README:用模板并替换日期占位
$readme = Get-Content (Join-Path $tplDir 'README-部署说明.txt') -Raw -Encoding UTF8