build.ps1 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # DMS 一体化构建脚本
  2. # 用法:在项目根目录执行 .\build\build.ps1
  3. [CmdletBinding()]
  4. param(
  5. [switch]$SkipFrontend,
  6. [switch]$SkipPyInstallerInstall
  7. )
  8. $ErrorActionPreference = "Stop"
  9. $ProjectRoot = Split-Path $PSScriptRoot -Parent
  10. $Backend = Join-Path $ProjectRoot "backend"
  11. $Frontend = Join-Path $ProjectRoot "frontend"
  12. $Dist = Join-Path $ProjectRoot "dist-package"
  13. $BuildCache = Join-Path $PSScriptRoot "__pycache_build"
  14. Write-Host "========== DMS 一体化构建 ==========" -ForegroundColor Cyan
  15. Write-Host "项目根目录: $ProjectRoot"
  16. # ---------- 1. 前端构建 ----------
  17. if (-not $SkipFrontend) {
  18. Write-Host "`n[1/5] 构建前端..." -ForegroundColor Yellow
  19. Push-Location $Frontend
  20. try {
  21. if (-not (Test-Path "node_modules")) {
  22. Write-Host " npm install..." -ForegroundColor DarkGray
  23. npm install
  24. if ($LASTEXITCODE -ne 0) { throw "npm install 失败" }
  25. }
  26. npm run build
  27. if ($LASTEXITCODE -ne 0) { throw "前端构建失败" }
  28. } finally { Pop-Location }
  29. } else {
  30. Write-Host "`n[1/5] 跳过前端构建 (-SkipFrontend)" -ForegroundColor DarkGray
  31. }
  32. $indexHtml = Join-Path $Frontend "dist\index.html"
  33. if (-not (Test-Path $indexHtml)) {
  34. throw "前端产物不存在: $indexHtml - 请先执行 npm run build"
  35. }
  36. # ---------- 2. 检查 PyInstaller ----------
  37. Write-Host "`n[2/5] 检查 PyInstaller..." -ForegroundColor Yellow
  38. Push-Location $Backend
  39. try {
  40. $pyinstallerVersion = & python -m PyInstaller --version 2>$null
  41. if ($LASTEXITCODE -ne 0 -or -not $pyinstallerVersion) {
  42. if ($SkipPyInstallerInstall) {
  43. throw "PyInstaller 未安装且 -SkipPyInstallerInstall 已指定"
  44. }
  45. Write-Host " 安装 PyInstaller..." -ForegroundColor DarkGray
  46. python -m pip install pyinstaller
  47. if ($LASTEXITCODE -ne 0) { throw "PyInstaller 安装失败" }
  48. } else {
  49. Write-Host " PyInstaller 版本: $pyinstallerVersion" -ForegroundColor DarkGray
  50. }
  51. } finally { Pop-Location }
  52. # ---------- 3. PyInstaller 打包 ----------
  53. Write-Host "`n[3/5] PyInstaller 打包..." -ForegroundColor Yellow
  54. if (Test-Path $BuildCache) { Remove-Item $BuildCache -Recurse -Force }
  55. if (Test-Path (Join-Path $Dist "dms-server")) {
  56. Remove-Item (Join-Path $Dist "dms-server") -Recurse -Force
  57. }
  58. Push-Location $Backend
  59. try {
  60. python -m PyInstaller `
  61. --noconfirm `
  62. --clean `
  63. --distpath $Dist `
  64. --workpath $BuildCache `
  65. (Join-Path $PSScriptRoot "dms-server.spec")
  66. if ($LASTEXITCODE -ne 0) { throw "PyInstaller 打包失败" }
  67. } finally { Pop-Location }
  68. # ---------- 4. 整理发行包 ----------
  69. Write-Host "`n[4/5] 整理发行包..." -ForegroundColor Yellow
  70. $ReleaseDir = Join-Path $Dist "dms-server"
  71. if (-not (Test-Path $ReleaseDir)) { throw "发行目录未找到: $ReleaseDir" }
  72. # 复制配置模板(不含真实 .env,保护凭据)
  73. Copy-Item (Join-Path $Backend ".env.example") $ReleaseDir -Force
  74. # 尝试调用项目自带的导出工具,把示例数据库导出为 SQL 文件
  75. $ExportTool = Join-Path $ProjectRoot "tools\export_full_demo_data.py"
  76. $ExportedSql = Join-Path $ReleaseDir "database-init.sql"
  77. if (Test-Path $ExportTool) {
  78. Write-Host " 导出示例数据库 SQL..." -ForegroundColor DarkGray
  79. Push-Location $Backend
  80. try {
  81. # 通过当前 Python 环境运行导出工具
  82. python $ExportTool --output $ExportedSql 2>&1 | Out-Host
  83. # 不判断退出码(不同版本的导出工具参数可能不同),仅检查产物
  84. if (-not (Test-Path $ExportedSql)) {
  85. Write-Warning "导出工具未生成 $ExportedSql,请手动准备 SQL 文件"
  86. }
  87. } catch {
  88. Write-Warning "导出工具执行失败:$_"
  89. } finally { Pop-Location }
  90. } else {
  91. Write-Warning "未找到 tools\export_full_demo_data.py,跳过自动导出"
  92. }
  93. # 复制说明文档
  94. Copy-Item (Join-Path $PSScriptRoot "README.txt") $ReleaseDir -Force
  95. # ---------- 5. 从备份恢复 .env 和 dms-storage ----------
  96. Write-Host "`n[5/5] 从备份恢复 .env 和 dms-storage..." -ForegroundColor Yellow
  97. $BackupDir = Join-Path $ProjectRoot "dist-package-bak\dms-server"
  98. if (-not (Test-Path $BackupDir)) {
  99. Write-Warning "备份目录不存在: $BackupDir - 跳过恢复"
  100. } else {
  101. $BackupEnv = Join-Path $BackupDir ".env"
  102. if (Test-Path $BackupEnv) {
  103. Copy-Item $BackupEnv $ReleaseDir -Force
  104. Write-Host " 已恢复 .env" -ForegroundColor DarkGray
  105. } else {
  106. Write-Warning "备份中没有 .env,跳过"
  107. }
  108. $BackupStorage = Join-Path $BackupDir "dms-storage"
  109. if (Test-Path $BackupStorage) {
  110. $TargetStorage = Join-Path $ReleaseDir "dms-storage"
  111. if (Test-Path $TargetStorage) {
  112. Remove-Item $TargetStorage -Recurse -Force
  113. }
  114. Copy-Item $BackupStorage $TargetStorage -Recurse -Force
  115. Write-Host " 已恢复 dms-storage" -ForegroundColor DarkGray
  116. } else {
  117. Write-Warning "备份中没有 dms-storage,跳过"
  118. }
  119. }
  120. Write-Host "`n========== 构建完成 ==========" -ForegroundColor Green
  121. Write-Host "发行包目录: $ReleaseDir" -ForegroundColor Green
  122. $sizeMB = [math]::Round((Get-ChildItem $ReleaseDir -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB, 1)
  123. Write-Host "包大小: ${sizeMB} MB" -ForegroundColor Green
  124. Write-Host "将该目录整体压缩即可分发给最终用户" -ForegroundColor Green