# GVSite 前端部署脚本:备份原站页面 → 全量编译 → 同步产物到生产目录(TempLate) # # 用途: # 1. 备份已被 Vue 页面替换的 TempLate 原始文件到 backup/www # 2. 全量重新构建(vue-tsc 类型检查 + vite build) # 3. 同步 dist 产物到 TempLate(index.html + assets) # 4. 校验产物一致性 # # 前置条件: # 1. 已修改 gvsds/apps/core/views.py 中的 SUBDOMAIN_CONFIG: # - www: 移除 'use_base': True(SPA 不再使用 _Base 模板) # - invite: dir 从 'Invite' 改为 '' 且移除 'use_base': True # 2. GVSite 路由已使用 createWebHistory(支持干净 URL) # # 用法: # PowerShell 中执行: .\deploy.ps1 # (若报执行策略限制: Set-ExecutionPolicy -Scope Process Bypass 后再执行) $ErrorActionPreference = 'Stop' $ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path # d:\SMANAGE\GVSite $DistDir = Join-Path $ProjectRoot 'dist' $TemplateRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'TempLate' # d:\SMANAGE\TempLate $BackupRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'backup\www' # d:\SMANAGE\backup\www Write-Host "`n===== GVSite 部署开始 =====" -ForegroundColor Cyan Write-Host "工程目录: $ProjectRoot" Write-Host "生产目录: $TemplateRoot" Write-Host "备份目录: $BackupRoot" Write-Host "" # ===================== # 0. 前置检查:确保 views.py 已更新 # ===================== Write-Host '[0/6] 前置检查...' -ForegroundColor Yellow $ViewsPy = Join-Path (Split-Path -Parent $ProjectRoot) 'gvsds\apps\core\views.py' $ViewsContent = Get-Content $ViewsPy -Raw if ($ViewsContent -match "'www':\s*\{'dir':\s*'',\s*'root_is_index':\s*True\s*\}") { Write-Host ' www 子域配置检查通过(无 use_base)' -ForegroundColor Green } else { Write-Warning ' www 子域配置可能仍有 use_base,请检查 views.py' } if ($ViewsContent -match "'invite':\s*\{'dir':\s*'',\s*'root_is_index':\s*True\s*\}") { Write-Host ' invite 子域配置检查通过(dir 改为空,无 use_base)' -ForegroundColor Green } else { Write-Warning ' invite 子域配置可能未更新,请检查 views.py' } Write-Host '' # ===================== # 1. 备份被替换的原始页面 # ===================== Write-Host '[1/6] 备份已被替换的 www + invite 原始页面...' -ForegroundColor Yellow # 需要备份的文件列表(相对 TempLate 的路径) $BackupFiles = @( # 根目录页面 'index.html', 'about.html', 'login.html', 'register.html', 'gallery.html', 'ContactUS.html', 'members.html', 'IntegrityReport.html', 'usercard.html', # 错误页面 'Errors/404.html', 'Errors/500.html', 'Errors/503.html', 'Errors/_403_HOST.html', # 项目页面 'ProJect/Unauthorized.html', # Invite 页面(模板文件保留不移除) 'Invite/index.html', 'Invite/interview.html' ) $BackupCount = 0 foreach ($relPath in $BackupFiles) { $sourceFile = Join-Path $TemplateRoot $relPath $destFile = Join-Path $BackupRoot $relPath if (Test-Path $sourceFile) { # 确保目标目录存在 $destDir = Split-Path $destFile -Parent if (-not (Test-Path $destDir)) { New-Item -ItemType Directory -Path $destDir -Force | Out-Null } Copy-Item -Path $sourceFile -Destination $destFile -Force Write-Host " 已备份: $relPath" $BackupCount++ } else { Write-Host " 跳过(不存在): $relPath" -ForegroundColor DarkGray } } if ($BackupCount -gt 0) { Write-Host " 备份完成,共 $BackupCount 个文件" -ForegroundColor Green } else { Write-Host " 无文件需要备份" -ForegroundColor Yellow } Write-Host '' # ===================== # 2. 清理旧构建产物 # ===================== Write-Host '[2/6] 清理旧构建产物...' -ForegroundColor Yellow if (Test-Path $DistDir) { Remove-Item -Recurse -Force $DistDir Write-Host " 已删除: $DistDir" } # 清理 TempLate/GVSite 旧产物目录(构建产物统一收敛到该子目录) $ProdGvsiteDir = Join-Path $TemplateRoot 'GVSite' if (Test-Path $ProdGvsiteDir) { Get-ChildItem -Path $ProdGvsiteDir -Recurse -Force | Remove-Item -Recurse -Force Write-Host " 已清理旧产物目录: GVSite/" } else { Write-Host " GVSite 目录不存在,跳过" -ForegroundColor DarkGray } Write-Host '' # ===================== # 3. 全量构建 # ===================== Write-Host '[3/6] 执行 npm run build(类型检查 + 全量编译)...' -ForegroundColor Yellow Push-Location $ProjectRoot try { npm run build if ($LASTEXITCODE -ne 0) { throw "构建失败,exit code = $LASTEXITCODE" } } finally { Pop-Location } Write-Host ' 构建成功' Write-Host '' # ===================== # 4. 同步产物到生产目录 # ===================== Write-Host '[4/6] 同步产物到 www 生产目录...' -ForegroundColor Yellow # 复制 GVSite 构建产物到生产目录 GVSite/(vite assetsDir=GVSite,产物位于 dist/GVSite/,相对引用 GVSite/...) $ProdGvsite = Join-Path $TemplateRoot 'GVSite' $DistGvsite = Join-Path $DistDir 'GVSite' if (Test-Path $DistGvsite) { if (-not (Test-Path $ProdGvsite)) { New-Item -ItemType Directory -Path $ProdGvsite -Force | Out-Null } # 先清空旧产物,避免 hash 文件堆积 Get-ChildItem -Path $ProdGvsite -File -ErrorAction SilentlyContinue | Remove-Item -Force Copy-Item -Recurse -Force (Join-Path $DistGvsite '*') $ProdGvsite Write-Host " 已同步: GVSite/" } else { Write-Warning " dist 中未找到 GVSite,请检查 vite.config.ts 的 assetsDir 配置" } # 复制 index.html(产物引用为 /GVSite/...,与部署位置 GVSite/ 一致,无需改写) $DistIndex = Join-Path $DistDir 'index.html' $ProdIndex = Join-Path $TemplateRoot 'index.html' if (Test-Path $DistIndex) { Copy-Item -Force $DistIndex $ProdIndex Write-Host " 已同步: index.html" } Write-Host ' 同步完成' Write-Host '' # ===================== # 5. 校验产物一致性 # ===================== Write-Host '[5/6] 校验产物一致性...' -ForegroundColor Yellow # 校验 index.html 存在 if (-not (Test-Path $ProdIndex)) { throw "index.html 不存在于生产目录: $ProdIndex" } # 校验 index.html 引用的入口 JS 存在 $indexContent = Get-Content $ProdIndex -Raw $entryMatch = [regex]::Match($indexContent, 'src="([^"]+\.js)"') if ($entryMatch.Success) { $entryPath = Join-Path $TemplateRoot ($entryMatch.Groups[1].Value.TrimStart('/')) if (Test-Path $entryPath) { Write-Host " 入口 JS 校验通过: $($entryMatch.Groups[1].Value)" -ForegroundColor Green } else { throw "index.html 引用的入口 JS 不存在: $entryPath" } } else { throw 'index.html 中未找到入口 JS 引用' } # 校验 assets 文件存在 $ProdAssetFiles = @(Get-ChildItem -Path $ProdGvsite -Recurse -File 2>$null) $DistAssetFiles = @(Get-ChildItem -Path $DistGvsite -Recurse -File 2>$null) if ($ProdAssetFiles.Count -ge $DistAssetFiles.Count) { Write-Host " assets 文件数: $($ProdAssetFiles.Count) 个(dist: $($DistAssetFiles.Count) 个)" -ForegroundColor Green } else { Write-Host " assets 文件数: $($ProdAssetFiles.Count) 个(dist: $($DistAssetFiles.Count) 个)" -ForegroundColor Yellow } Write-Host '' Write-Host "===== GVSite 部署完成 =====" -ForegroundColor Cyan Write-Host "备份位置: $BackupRoot" -ForegroundColor Cyan Write-Host "请浏览器强制刷新(Ctrl+F5)加载新产物。" -ForegroundColor Cyan Write-Host '' Write-Host '===== 部署后提醒 =====' -ForegroundColor Magenta Write-Host ' - www.gvsds.com 和 invite.gvsds.com 现在使用 GVSite SPA(createWebHistory)' Write-Host ' - 旧 _Base 模板已不再使用,所有页面由 Vue Router 前端路由控制' Write-Host ' - 原始文件已备份到 backup/www,可随时恢复' Write-Host ' - 旧 .html 文件仍保留在 TempLate 中作为降级回退' Write-Host ' - 如需回退:删除 TempLate/index.html 和 GVSite 的 assets,恢复 backup/www 中的文件' Write-Host '================================================================================' -ForegroundColor Magenta