From 89495b99f06cd9d897105759924d7b73ae907b44 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期六, 03 十月 2026 11:46:07 +0800
Subject: [PATCH] fix(部署): pack-deploy 补齐外置配置/启动脚本/docs/web 并修正模板端口(8090)

---
 pack-deploy.ps1 |  138 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 106 insertions(+), 32 deletions(-)

diff --git a/pack-deploy.ps1 b/pack-deploy.ps1
index 42cc00d..1e31977 100644
--- a/pack-deploy.ps1
+++ b/pack-deploy.ps1
@@ -1,34 +1,75 @@
 锘�<#
-  涓�閿墦鍖呴儴缃插寘锛堝惈"鍘诲瘑鑷"锛夆�斺�� 2026-09-27 鏂板
+  涓�閿墦鍖呴儴缃插寘锛堝惈"鍘诲瘑鑷"锛夆�斺�� 2026-09-27 鏂板锛�2026-10-03 淇
   鐢ㄦ硶锛�
     powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1
     powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1 -OutRoot "E:\璇曢獙" -SkipFrontend
-  鍋氬洓浠朵簨锛�
-    1) mvn clean package 鏋勫缓鍚庣 jar
+
+  鍋氫簲浠朵簨锛�
+    1) 鐢� deploy-templates\jar-application.yml锛堝叏鍗犱綅绗︼級涓存椂鏇挎崲婧愮爜 application.yml锛�
+       鎵ц mvn clean package锛涙棤璁烘垚璐ラ兘杩樺師寮�鍙戞満鐪熷疄閰嶇疆
     2) 瑙e帇 jar 妫�鏌ュ唴缃� application.yml锛氬繀椤诲叏鏄崰浣嶇锛堢姝� sk- 瀵嗛挜 / 鏄庢枃鍙d护锛夛紝涓嶅悎鏍肩洿鎺ヤ腑姝�
-    3) npm run build 鏋勫缓鍓嶇 dist锛堝彲 -SkipFrontend锛�
-    4) 缁勮 deploy 鐩綍缁撴瀯锛坆ackend / frontend / db / README-閮ㄧ讲璇存槑.txt锛夛紝杈撳嚭鍒� <OutRoot>\traffic-audit-deploy-<yyyyMMdd>
+    3) npm run build 閲嶅缓鍓嶇 dist锛堝彲 -SkipFrontend锛�
+    4) 缁勮瀹屾暣閮ㄧ讲鍖咃細backend(jar + application.yml + 鍚姩鑴氭湰 + docs + web) / frontend/dist / db / README
+    5) 瀵圭粍瑁呭悗鐨勬暣鍖呭啀鎵竴閬嶆槑鏂囧瘑閽�
+
+  淇鑳屾櫙锛�2026-10-03锛夛細2026-10-02 鎵嬪伐浜у嚭鐨勫寘缂� application.yml / docs / db / 鍚姩鑴氭湰锛�
+  涓旀病鏈夋妸 dist 鍚屾鍒� backend\web锛岄儴缃叉満鍚姩鐩存帴鎶�
+  "java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)"銆�
+  鏈増鎶婁笂杩版枃浠跺叏閮ㄨˉ榻愶紝骞舵寜 jar 鍐呯疆鍗犱綅绗﹂厤缃噸鏂版瀯寤猴紝閬垮厤鍐嶆鍑虹幇銆�
 #>
 param(
-  [string]$OutRoot = 'E:\璇曢獙',
-  [switch]$SkipFrontend
+  [string]$OutRoot = '',
+  [switch]$SkipFrontend,
+  [switch]$SkipBackend      # 澶嶇敤宸插瓨鍦ㄧ殑 jar锛堜笉閲嶇紪璇戙�佷笉鍔ㄦ簮鐮侀厤缃級锛屼粎鐢ㄤ簬琛ュ叏/閲嶇粍鍙戝竷鍖�
 )
 
 $ErrorActionPreference = 'Stop'
 $root = Split-Path -Parent $MyInvocation.MyCommand.Path
-$tplDir = Join-Path $root 'deploy-templates'                  # 鎵撳寘妯℃澘浠讹紙宸插叆搴擄紝2026-09-27 璧凤級
-$jarRel = 'traffic-audit-server\target\traffic-audit-server-1.0.0-SNAPSHOT.jar'
-$jar = Join-Path $root $jarRel
+if (-not $OutRoot) { $OutRoot = Join-Path $root 'deploy' }      # 榛樿杈撳嚭鍒颁粨搴� deploy\锛堝凡 gitignore锛�
+$tplDir    = Join-Path $root 'deploy-templates'                  # 鎵撳寘妯℃澘浠讹紙宸插叆搴擄級
+$tplJarCfg = Join-Path $tplDir 'jar-application.yml'             # 杩� jar 鐨勫崰浣嶇閰嶇疆
+$srcCfg    = Join-Path $root 'traffic-audit-server\src\main\resources\application.yml'
+$jarRel    = 'traffic-audit-server\target\traffic-audit-server-1.0.0-SNAPSHOT.jar'
+$jar       = Join-Path $root $jarRel
+$webDist   = Join-Path $root 'traffic-audit-web\dist'
 
-Write-Host '[1/5] 鏋勫缓鍚庣锛坢vn clean package -DskipTests锛�...'
-Push-Location $root
-cmd /c "mvn.cmd -q clean package -DskipTests -f traffic-audit-server\pom.xml > pack-build.log 2>&1"
-$rc = $LASTEXITCODE
-Pop-Location
-if ($rc -ne 0) { throw '鍚庣鏋勫缓澶辫触锛岃瑙� pack-build.log' }
+if (-not (Test-Path $tplJarCfg)) { throw "缂哄皯鎵撳寘妯℃澘锛�$tplJarCfg" }
+
+# ---------- [1/5] 鐢ㄥ崰浣嶇閰嶇疆鏋勫缓 jar锛屾瀯寤哄悗杩樺師寮�鍙戞満鐪熷疄閰嶇疆 ----------
+if ($SkipBackend) {
+  Write-Host '[1/5] 宸叉寚瀹� -SkipBackend锛岃烦杩囧悗绔瀯寤猴紝澶嶇敤鐜版湁 jar'
+  if (-not (Test-Path $jar)) { throw "鏈壘鍒扮幇鏈� jar锛�$jar锛堝幓鎺� -SkipBackend 閲嶆柊鏋勫缓锛�" }
+} else {
+Write-Host '[1/5] 鏋勫缓鍚庣锛坢vn clean package -DskipTests锛屾瀯寤烘湡浣跨敤鍗犱綅绗﹂厤缃級...'
+$backupCfg = $null
+$hadCfg = Test-Path $srcCfg
+try {
+  if ($hadCfg) {
+    $backupCfg = [System.IO.Path]::GetTempFileName()
+    Copy-Item $srcCfg $backupCfg -Force
+  }
+  Copy-Item $tplJarCfg $srcCfg -Force
+  Push-Location $root
+  try {
+    cmd /c "mvn.cmd -q clean package -DskipTests -f traffic-audit-server\pom.xml > pack-build.log 2>&1"
+    $rc = $LASTEXITCODE
+  } finally { Pop-Location }
+  if ($rc -ne 0) { throw '鍚庣鏋勫缓澶辫触锛岃瑙� pack-build.log' }
+} finally {
+  if ($backupCfg) {
+    Copy-Item $backupCfg $srcCfg -Force
+    Remove-Item $backupCfg -Force -ErrorAction SilentlyContinue
+    Write-Host '      宸茶繕鍘熷紑鍙戞満 src\main\resources\application.yml'
+  } elseif (-not $hadCfg) {
+    Remove-Item $srcCfg -Force -ErrorAction SilentlyContinue
+    Write-Host '      娉ㄦ剰锛氭瀯寤哄墠婧愮爜鐩綍鏈潵娌℃湁 application.yml锛屽凡娓呮帀涓存椂鍗犱綅绗︽枃浠�'
+  }
+}
 if (-not (Test-Path $jar)) { throw "鏈壘鍒版瀯寤轰骇鐗╋細$jar" }
+}
 Write-Host ("      浜х墿锛歿0:N1} MB" -f ((Get-Item $jar).Length / 1MB))
 
+# ---------- [2/5] 鍘诲瘑鑷锛歫ar 鍐呯疆閰嶇疆蹇呴』鍏ㄦ槸鍗犱綅绗� ----------
 Write-Host '[2/5] 鍘诲瘑鑷锛氳В鍘� jar 妫�鏌� BOOT-INF/classes/application.yml ...'
 Add-Type -AssemblyName System.IO.Compression.FileSystem
 $zip = [System.IO.Compression.ZipFile]::OpenRead($jar)
@@ -40,29 +81,43 @@
   $sr.Close()
 } finally { $zip.Dispose() }
 
-$bad = @()
-if ($text -match 'sk-[A-Za-z0-9]{16,}') { $bad += '鐤戜技鏄庢枃 API key锛坰k-鈥︼級' }
-foreach ($line in ($text -split "`n")) {
-  if ($line -match '^\s*(password|api-key|secret)\s*:\s*(.+)$') {
-    $v = $matches[2].Trim().Trim('"')
-    if ($v -and -not $v.StartsWith('${')) { $bad += ("$($matches[1]) 涓嶆槸鍗犱綅绗�") }
+function Get-SecretHits([string]$ymlText) {
+  $hits = @()
+  if ($ymlText -match 'sk-[A-Za-z0-9]{16,}') { $hits += '鐤戜技鏄庢枃 API key(sk-...)' }
+  foreach ($line in ($ymlText -split "`n")) {
+    if ($line -match '^\s*(password|api-key|secret)\s*:\s*(.+)$') {
+      $v = $matches[2].Trim().Trim('"')
+      if ($v -and -not $v.StartsWith('${')) { $hits += ("$($matches[1]) 涓嶆槸鍗犱綅绗�") }
+    }
   }
+  return $hits
 }
+
+$bad = Get-SecretHits $text
 if ($bad.Count -gt 0) {
-  throw ('鍘诲瘑鑷鏈�氳繃锛�' + ($bad -join '锛�') + '銆傝妫�鏌� traffic-audit-server\src\main\resources\application.yml')
+  throw ('鍘诲瘑鑷鏈�氳繃锛�' + ($bad -join '锛�') + "銆傝妫�鏌� $tplJarCfg")
+}
+if ($text -notmatch 'password:\s*\$\{TRAFFIC_DB_PASSWORD') {
+  Write-Host '      璀﹀憡锛歫ar 鍐呯疆 password 涓嶆槸 TRAFFIC_DB_PASSWORD 鍗犱綅绗﹀舰寮忥紝璇风‘璁ゆā鏉裤��'
 }
 Write-Host '      閫氳繃锛歫ar 鍐呯疆閰嶇疆鍏ㄩ儴涓哄崰浣嶇锛屾棤鏄庢枃瀵嗛挜/鍙d护銆�'
 
+# ---------- [3/5] 鍓嶇鏋勫缓 ----------
 Write-Host '[3/5] 鏋勫缓鍓嶇锛坣pm run build锛屽彲 -SkipFrontend 璺宠繃锛�...'
 if (-not $SkipFrontend) {
   Push-Location (Join-Path $root 'traffic-audit-web')
-  cmd /c "npm.cmd run build > ..\pack-front.log 2>&1"
-  $rc2 = $LASTEXITCODE
-  Pop-Location
+  try {
+    cmd /c "npm.cmd run build > ..\pack-front.log 2>&1"
+    $rc2 = $LASTEXITCODE
+  } finally { Pop-Location }
   if ($rc2 -ne 0) { throw '鍓嶇鏋勫缓澶辫触锛岃瑙� pack-front.log' }
   Write-Host '      鍓嶇 dist 宸查噸寤�'
+} else {
+  Write-Host '      宸叉寜 -SkipFrontend 璺宠繃锛屼娇鐢ㄧ幇鏈� dist'
 }
+if (-not (Test-Path $webDist)) { throw "鏈壘鍒板墠绔骇鐗╋細$webDist锛堝幓鎺� -SkipFrontend 閲嶆柊鏋勫缓锛�" }
 
+# ---------- [4/5] 缁勮瀹屾暣閮ㄧ讲鐩綍 ----------
 Write-Host '[4/5] 缁勮閮ㄧ讲鐩綍...'
 $stamp = Get-Date -Format 'yyyyMMdd'
 $dest = Join-Path $OutRoot ("traffic-audit-deploy-" + $stamp)
@@ -74,9 +129,12 @@
 Copy-Item (Join-Path $tplDir 'backend\application.yml') (Join-Path $dest 'backend') -Force
 Copy-Item (Join-Path $tplDir 'backend\start-backend.cmd') (Join-Path $dest 'backend') -Force
 Copy-Item (Join-Path $tplDir 'backend\start-backend.sh') (Join-Path $dest 'backend') -Force
-Copy-Item (Join-Path $root 'traffic-audit-web\dist') (Join-Path $dest 'frontend') -Recurse -Force
+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 鍐呭涓�鑷�
+Copy-Item $webDist (Join-Path $dest 'backend\web') -Recurse -Force
 
 # docs锛氳繍琛屾椂妯℃澘 + 鐢ㄦ埛鏂囨。锛涙帓闄ゅ紑鍙戣繃绋嬫枃妗d笌缂撳瓨/澶囦唤锛堝噺灏忎綋绉�侀伩鍏嶆妸鍐呴儴娓呭崟甯﹀嚭鍘伙級
 $docsDest = Join-Path $dest 'backend\docs'
@@ -84,15 +142,31 @@
 cmd /c "robocopy `"$root\docs`" `"$docsDest`" /E /NFL /NDL /NJH /NJS /NP /XD _cache 宸ヤ綔鏃ョ粨 鍔熻兘娴嬭瘯鎶ュ憡 闂姹囨�� /XF 鐢熸垚_*.xlsx _bak_* >nul"
 if ($LASTEXITCODE -ge 8) { throw "docs 澶嶅埗澶辫触锛坮obocopy 杩斿洖 $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') $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') $docsDest -Force -ErrorAction SilentlyContinue
 
-# README锛氱敤鏃у寘妯℃澘骞舵浛鎹㈡棩鏈熷崰浣�
+# README锛氱敤妯℃澘骞舵浛鎹㈡棩鏈熷崰浣�
 $readme = Get-Content (Join-Path $tplDir 'README-閮ㄧ讲璇存槑.txt') -Raw -Encoding UTF8
 $readme = $readme.Replace('{stamp}', $stamp)
 Set-Content -LiteralPath (Join-Path $dest 'README-閮ㄧ讲璇存槑.txt') -Value $readme -Encoding UTF8
 
-Write-Host '[5/5] 姹囨��...'
+# ---------- [5/5] 鏁村寘鏄庢枃瀵嗛挜鎵弿 + 姹囨�� ----------
+Write-Host '[5/5] 鏁村寘鎵弿 + 姹囨��...'
+$leak = @()
+foreach ($f in (Get-ChildItem (Join-Path $dest 'backend') -File | Where-Object { $_.Extension -in '.yml', '.yaml', '.cmd', '.sh', '.txt' })) {
+  $t = Get-Content $f.FullName -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
+  if ($t -and $t -match 'sk-[A-Za-z0-9]{16,}') { $leak += $f.Name + '(鐤戜技鏄庢枃 API key)' }
+}
+if ($leak.Count -gt 0) { throw ('鏁村寘鎵弿鏈�氳繃锛�' + ($leak -join '锛�')) }
+
 $files = Get-ChildItem $dest -Recurse -File
+$mb = (($files | Measure-Object Length -Sum).Sum / 1MB)
 Write-Host ("      杈撳嚭鐩綍锛歿0}" -f $dest)
-Write-Host ("      鏂囦欢鏁帮細{0}銆�鍚堣锛歿1:N2} MB" -f $files.Count, (($files | Measure-Object Length -Sum).Sum / 1MB))
-Write-Host '      鎻愰啋锛氭妸鍖呮嫹鍒伴儴缃叉満鍚庯紝鍙渶鏀� backend\application.yml 閲岀殑鏁版嵁搴撲笁澶� + 闇�瑕佹椂濉� deepseek.api-key銆�'
+Write-Host ("      鏂囦欢鏁帮細{0}  鍚堣锛歿1:N2} MB" -f $files.Count, $mb)
+
+$zipPath = $dest + '.zip'
+if (Get-Command Compress-Archive -ErrorAction SilentlyContinue) {
+  if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
+  Compress-Archive -Path (Join-Path $dest '*') -DestinationPath $zipPath -CompressionLevel Optimal
+  Write-Host ("      鍘嬬缉鍖咃細{0}锛坽1:N2} MB锛�" -f $zipPath, ((Get-Item $zipPath).Length / 1MB))
+}
+Write-Host '      鎻愰啋锛氭嫹鍒伴儴缃叉満鍚庯紝鍔″繀鍏堟敼 backend\application.yml 鐨� spring.datasource锛坲rl/username/password锛夊啀鍚姩銆�'

--
Gitblit v1.9.1