- Add sidecar management to backend (sidecar_manager.py) - Add sidecar API router for browser mode (/api/sidecar/*) - Add browser-api.js polyfill for running in Chrome/Edge - Add "Open in Browser" button when audio access fails - Update build scripts with new sidecar modules - Add start-browser.sh for development browser mode Browser mode allows users to open the app in their system browser when Electron's audio access is blocked by security software. The backend manages the sidecar process in browser mode (BROWSER_MODE=true). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
625 lines
20 KiB
Batchfile
625 lines
20 KiB
Batchfile
@echo off
|
||
chcp 65001 >nul
|
||
REM Meeting Assistant Client - Windows 打包腳本
|
||
REM 將 Electron 應用與 Python Sidecar 打包成免安裝 exe
|
||
|
||
setlocal enabledelayedexpansion
|
||
|
||
REM 顏色設定 (Windows 10+)
|
||
set "GREEN=[92m"
|
||
set "YELLOW=[93m"
|
||
set "RED=[91m"
|
||
set "BLUE=[94m"
|
||
set "CYAN=[96m"
|
||
set "NC=[0m"
|
||
|
||
REM 專案路徑
|
||
set "SCRIPT_DIR=%~dp0"
|
||
set "PROJECT_DIR=%SCRIPT_DIR%.."
|
||
set "CLIENT_DIR=%PROJECT_DIR%\client"
|
||
set "SIDECAR_DIR=%PROJECT_DIR%\sidecar"
|
||
set "BACKEND_DIR=%PROJECT_DIR%\backend"
|
||
set "BUILD_DIR=%PROJECT_DIR%\build"
|
||
|
||
REM 預設配置
|
||
set "SKIP_SIDECAR=false"
|
||
set "SKIP_BACKEND=true"
|
||
set "EMBEDDED_BACKEND=false"
|
||
set "CLEAN_BUILD=false"
|
||
set "API_URL="
|
||
set "DATABASE_TYPE="
|
||
set "BUILD_TARGET=nsis"
|
||
|
||
REM 解析參數
|
||
set "COMMAND=help"
|
||
:parse_args
|
||
if "%~1"=="" goto :main
|
||
if /i "%~1"=="build" (set "COMMAND=build" & shift & goto :parse_args)
|
||
if /i "%~1"=="sidecar" (set "COMMAND=sidecar" & shift & goto :parse_args)
|
||
if /i "%~1"=="electron" (set "COMMAND=electron" & shift & goto :parse_args)
|
||
if /i "%~1"=="clean" (set "COMMAND=clean" & shift & goto :parse_args)
|
||
if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args)
|
||
if /i "%~1"=="--skip-sidecar" (set "SKIP_SIDECAR=true" & shift & goto :parse_args)
|
||
if /i "%~1"=="--skip-backend" (set "SKIP_BACKEND=true" & shift & goto :parse_args)
|
||
if /i "%~1"=="--embedded-backend" (set "EMBEDDED_BACKEND=true" & set "SKIP_BACKEND=false" & shift & goto :parse_args)
|
||
if /i "%~1"=="--clean" (set "CLEAN_BUILD=true" & shift & goto :parse_args)
|
||
if /i "%~1"=="--api-url" (set "API_URL=%~2" & shift & shift & goto :parse_args)
|
||
if /i "%~1"=="--database-type" (set "DATABASE_TYPE=%~2" & shift & shift & goto :parse_args)
|
||
if /i "%~1"=="--target" (set "BUILD_TARGET=%~2" & shift & shift & goto :parse_args)
|
||
echo %RED%[ERROR]%NC% 未知參數: %~1
|
||
goto :show_help
|
||
|
||
:main
|
||
if "%COMMAND%"=="help" goto :show_help
|
||
if "%COMMAND%"=="build" goto :do_build
|
||
if "%COMMAND%"=="sidecar" goto :do_sidecar
|
||
if "%COMMAND%"=="electron" goto :do_electron
|
||
if "%COMMAND%"=="clean" goto :do_clean
|
||
goto :show_help
|
||
|
||
:show_banner
|
||
echo.
|
||
echo %CYAN%==========================================
|
||
echo Meeting Assistant Client Builder
|
||
echo 打包 Electron + Sidecar 為免安裝執行檔
|
||
echo ==========================================%NC%
|
||
echo.
|
||
goto :eof
|
||
|
||
:check_environment
|
||
echo %BLUE%[STEP]%NC% 檢查建置環境...
|
||
|
||
REM 檢查 Node.js
|
||
where node >nul 2>&1
|
||
if %errorlevel% equ 0 (
|
||
for /f "tokens=*" %%i in ('node --version') do echo %GREEN%[OK]%NC% Node.js: %%i
|
||
) else (
|
||
echo %RED%[ERROR]%NC% Node.js 未安裝
|
||
exit /b 1
|
||
)
|
||
|
||
REM 檢查 npm
|
||
where npm >nul 2>&1
|
||
if %errorlevel% equ 0 (
|
||
for /f "tokens=*" %%i in ('npm --version') do echo %GREEN%[OK]%NC% npm: %%i
|
||
) else (
|
||
echo %RED%[ERROR]%NC% npm 未安裝
|
||
exit /b 1
|
||
)
|
||
|
||
REM 檢查 Python
|
||
where python >nul 2>&1
|
||
if %errorlevel% equ 0 (
|
||
for /f "tokens=*" %%i in ('python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"') do set "PY_VERSION=%%i"
|
||
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.major)"') do set "PY_MAJOR=%%i"
|
||
for /f "tokens=*" %%i in ('python -c "import sys; print(sys.version_info.minor)"') do set "PY_MINOR=%%i"
|
||
|
||
if !PY_MAJOR! geq 3 if !PY_MINOR! geq 10 (
|
||
set "PYTHON_CMD=python"
|
||
echo %GREEN%[OK]%NC% Python !PY_VERSION!
|
||
goto :eof
|
||
)
|
||
)
|
||
|
||
echo %RED%[ERROR]%NC% 需要 Python 3.10 或更高版本
|
||
exit /b 1
|
||
|
||
:update_config
|
||
if "%API_URL%"=="" goto :eof
|
||
|
||
echo %BLUE%[STEP]%NC% 更新 API URL 設定...
|
||
|
||
set "CONFIG_FILE=%CLIENT_DIR%\config.json"
|
||
if not exist "%CONFIG_FILE%" (
|
||
echo %YELLOW%[WARN]%NC% 找不到 config.json,跳過 API URL 設定
|
||
goto :eof
|
||
)
|
||
|
||
REM 使用 PowerShell 更新 JSON
|
||
powershell -Command "$config = Get-Content '%CONFIG_FILE%' -Raw | ConvertFrom-Json; $config.apiBaseUrl = '%API_URL%'; $config | ConvertTo-Json -Depth 10 | Set-Content '%CONFIG_FILE%' -Encoding UTF8"
|
||
|
||
if errorlevel 1 (
|
||
echo %RED%[ERROR]%NC% 更新 config.json 失敗
|
||
exit /b 1
|
||
)
|
||
|
||
echo %GREEN%[OK]%NC% API URL 已設定為: %API_URL%
|
||
goto :eof
|
||
|
||
:do_clean
|
||
echo %BLUE%[STEP]%NC% 清理建置目錄...
|
||
|
||
if exist "%BUILD_DIR%" rmdir /s /q "%BUILD_DIR%"
|
||
if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist"
|
||
if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist"
|
||
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
|
||
if exist "%SIDECAR_DIR%\venv" rmdir /s /q "%SIDECAR_DIR%\venv"
|
||
if exist "%SIDECAR_DIR%\*.spec" del /q "%SIDECAR_DIR%\*.spec"
|
||
if exist "%BACKEND_DIR%\dist" rmdir /s /q "%BACKEND_DIR%\dist"
|
||
if exist "%BACKEND_DIR%\build" rmdir /s /q "%BACKEND_DIR%\build"
|
||
if exist "%BACKEND_DIR%\venv" rmdir /s /q "%BACKEND_DIR%\venv"
|
||
if exist "%BACKEND_DIR%\*.spec" del /q "%BACKEND_DIR%\*.spec"
|
||
|
||
echo %GREEN%[OK]%NC% 建置目錄已清理
|
||
goto :eof
|
||
|
||
:setup_sidecar_venv
|
||
echo %BLUE%[STEP]%NC% 設置 Sidecar 建置環境...
|
||
|
||
cd /d "%SIDECAR_DIR%"
|
||
|
||
if not exist "venv" (
|
||
echo %BLUE%[INFO]%NC% 創建虛擬環境...
|
||
%PYTHON_CMD% -m venv venv
|
||
)
|
||
|
||
echo %BLUE%[INFO]%NC% 安裝 Sidecar 依賴...
|
||
call venv\Scripts\activate.bat
|
||
python -m pip install --upgrade pip -q
|
||
python -m pip install -r requirements.txt -q
|
||
|
||
echo %BLUE%[INFO]%NC% 安裝 PyInstaller...
|
||
python -m pip install pyinstaller -q
|
||
|
||
echo %GREEN%[OK]%NC% Sidecar 建置環境就緒
|
||
goto :eof
|
||
|
||
:build_sidecar
|
||
echo %BLUE%[STEP]%NC% 打包 Sidecar (Python → 獨立執行檔)...
|
||
|
||
cd /d "%SIDECAR_DIR%"
|
||
|
||
call venv\Scripts\activate.bat
|
||
|
||
if not exist "dist" mkdir dist
|
||
|
||
echo %BLUE%[INFO]%NC% 執行 PyInstaller...
|
||
echo %BLUE%[INFO]%NC% 這可能需要幾分鐘...
|
||
|
||
pyinstaller ^
|
||
--onedir ^
|
||
--name transcriber ^
|
||
--distpath dist ^
|
||
--workpath build ^
|
||
--specpath . ^
|
||
--noconfirm ^
|
||
--clean ^
|
||
--log-level WARN ^
|
||
--console ^
|
||
--hidden-import=faster_whisper ^
|
||
--hidden-import=ctranslate2 ^
|
||
--hidden-import=huggingface_hub ^
|
||
--hidden-import=tokenizers ^
|
||
--hidden-import=onnxruntime ^
|
||
--hidden-import=opencc ^
|
||
--hidden-import=pydub ^
|
||
--hidden-import=numpy ^
|
||
--hidden-import=av ^
|
||
--collect-data=onnxruntime ^
|
||
--collect-data=faster_whisper ^
|
||
transcriber.py
|
||
|
||
if exist "dist\transcriber" (
|
||
echo %GREEN%[OK]%NC% Sidecar 打包完成: %SIDECAR_DIR%\dist\transcriber
|
||
) else (
|
||
echo %RED%[ERROR]%NC% Sidecar 打包失敗
|
||
exit /b 1
|
||
)
|
||
goto :eof
|
||
|
||
:setup_backend_venv
|
||
echo %BLUE%[STEP]%NC% 設置 Backend 建置環境...
|
||
|
||
cd /d "%BACKEND_DIR%"
|
||
|
||
if not exist "venv" (
|
||
echo %BLUE%[INFO]%NC% 創建虛擬環境...
|
||
%PYTHON_CMD% -m venv venv
|
||
)
|
||
|
||
echo %BLUE%[INFO]%NC% 安裝 Backend 依賴...
|
||
call venv\Scripts\activate.bat
|
||
python -m pip install --upgrade pip -q
|
||
python -m pip install -r requirements.txt -q
|
||
|
||
echo %BLUE%[INFO]%NC% 安裝 PyInstaller...
|
||
python -m pip install pyinstaller -q
|
||
|
||
echo %GREEN%[OK]%NC% Backend 建置環境就緒
|
||
goto :eof
|
||
|
||
:build_backend
|
||
echo %BLUE%[STEP]%NC% 打包 Backend (Python → 獨立執行檔)...
|
||
|
||
cd /d "%BACKEND_DIR%"
|
||
|
||
call venv\Scripts\activate.bat
|
||
|
||
if not exist "dist" mkdir dist
|
||
|
||
echo %BLUE%[INFO]%NC% 執行 PyInstaller...
|
||
echo %BLUE%[INFO]%NC% 這可能需要幾分鐘...
|
||
|
||
pyinstaller ^
|
||
--onedir ^
|
||
--name backend ^
|
||
--distpath dist ^
|
||
--workpath build ^
|
||
--specpath . ^
|
||
--noconfirm ^
|
||
--clean ^
|
||
--log-level WARN ^
|
||
--console ^
|
||
--hidden-import=uvicorn ^
|
||
--hidden-import=uvicorn.logging ^
|
||
--hidden-import=uvicorn.loops ^
|
||
--hidden-import=uvicorn.loops.auto ^
|
||
--hidden-import=uvicorn.protocols ^
|
||
--hidden-import=uvicorn.protocols.http ^
|
||
--hidden-import=uvicorn.protocols.http.auto ^
|
||
--hidden-import=uvicorn.protocols.websockets ^
|
||
--hidden-import=uvicorn.protocols.websockets.auto ^
|
||
--hidden-import=uvicorn.lifespan ^
|
||
--hidden-import=uvicorn.lifespan.on ^
|
||
--hidden-import=uvicorn.lifespan.off ^
|
||
--hidden-import=fastapi ^
|
||
--hidden-import=starlette ^
|
||
--hidden-import=pydantic ^
|
||
--hidden-import=pydantic_core ^
|
||
--hidden-import=mysql.connector ^
|
||
--hidden-import=mysql.connector.pooling ^
|
||
--hidden-import=sqlite3 ^
|
||
--hidden-import=httpx ^
|
||
--hidden-import=httpcore ^
|
||
--hidden-import=jose ^
|
||
--hidden-import=jose.jwt ^
|
||
--hidden-import=cryptography ^
|
||
--hidden-import=openpyxl ^
|
||
--hidden-import=multipart ^
|
||
--hidden-import=python_multipart ^
|
||
--hidden-import=dotenv ^
|
||
--hidden-import=tzdata ^
|
||
--hidden-import=app ^
|
||
--hidden-import=app.main ^
|
||
--hidden-import=app.config ^
|
||
--hidden-import=app.database ^
|
||
--hidden-import=app.models ^
|
||
--hidden-import=app.models.schemas ^
|
||
--hidden-import=app.routers ^
|
||
--hidden-import=app.routers.auth ^
|
||
--hidden-import=app.routers.meetings ^
|
||
--hidden-import=app.routers.ai ^
|
||
--hidden-import=app.routers.export ^
|
||
--hidden-import=app.routers.sidecar ^
|
||
--hidden-import=app.sidecar_manager ^
|
||
--collect-data=pydantic ^
|
||
--collect-data=uvicorn ^
|
||
run_server.py
|
||
|
||
if exist "dist\backend" (
|
||
echo %BLUE%[INFO]%NC% 複製 template 目錄...
|
||
if exist "template" (
|
||
xcopy /s /e /y "template\*" "dist\backend\template\" >nul 2>&1
|
||
)
|
||
if not exist "dist\backend\record" mkdir "dist\backend\record"
|
||
echo %GREEN%[OK]%NC% Backend 打包完成: %BACKEND_DIR%\dist\backend
|
||
) else (
|
||
echo %RED%[ERROR]%NC% Backend 打包失敗
|
||
exit /b 1
|
||
)
|
||
goto :eof
|
||
|
||
:update_config_embedded
|
||
REM 更新 config.json 以啟用 embedded backend
|
||
if "%EMBEDDED_BACKEND%"=="false" goto :eof
|
||
|
||
echo %BLUE%[STEP]%NC% 啟用內嵌後端模式...
|
||
|
||
set "CONFIG_FILE=%CLIENT_DIR%\config.json"
|
||
if not exist "%CONFIG_FILE%" (
|
||
echo %YELLOW%[WARN]%NC% 找不到 config.json,跳過內嵌模式設定
|
||
goto :eof
|
||
)
|
||
|
||
REM 使用 PowerShell 更新 backend.embedded = true (使用 UTF8 without BOM)
|
||
powershell -Command "$config = Get-Content '%CONFIG_FILE%' -Raw | ConvertFrom-Json; if (-not $config.backend) { $config | Add-Member -NotePropertyName 'backend' -NotePropertyValue @{} }; $config.backend.embedded = $true; $json = $config | ConvertTo-Json -Depth 10; [System.IO.File]::WriteAllText('%CONFIG_FILE%', $json, [System.Text.UTF8Encoding]::new($false))"
|
||
|
||
if errorlevel 1 (
|
||
echo %RED%[ERROR]%NC% 更新 config.json embedded 設定失敗
|
||
exit /b 1
|
||
)
|
||
|
||
echo %GREEN%[OK]%NC% 已啟用內嵌後端模式
|
||
goto :eof
|
||
|
||
:update_config_database
|
||
REM 更新 config.json 的資料庫類型
|
||
if "%DATABASE_TYPE%"=="" goto :eof
|
||
|
||
echo %BLUE%[STEP]%NC% 設定資料庫類型...
|
||
|
||
set "CONFIG_FILE=%CLIENT_DIR%\config.json"
|
||
if not exist "%CONFIG_FILE%" (
|
||
echo %YELLOW%[WARN]%NC% 找不到 config.json,跳過資料庫類型設定
|
||
goto :eof
|
||
)
|
||
|
||
REM 驗證資料庫類型
|
||
if /i not "%DATABASE_TYPE%"=="mysql" if /i not "%DATABASE_TYPE%"=="sqlite" (
|
||
echo %RED%[ERROR]%NC% 無效的資料庫類型: %DATABASE_TYPE%
|
||
echo %BLUE%[INFO]%NC% 有效選項: mysql, sqlite
|
||
exit /b 1
|
||
)
|
||
|
||
REM 使用 PowerShell 更新 database.type (使用 UTF8 without BOM)
|
||
if /i "%DATABASE_TYPE%"=="sqlite" (
|
||
REM SQLite 模式: 設定 type=sqlite,清空 MySQL 連線資訊
|
||
powershell -Command "$config = Get-Content '%CONFIG_FILE%' -Raw | ConvertFrom-Json; $config.backend.database.type = 'sqlite'; $config.backend.database.host = ''; $config.backend.database.user = ''; $config.backend.database.password = ''; $config.backend.database.database = ''; $json = $config | ConvertTo-Json -Depth 10; [System.IO.File]::WriteAllText('%CONFIG_FILE%', $json, [System.Text.UTF8Encoding]::new($false))"
|
||
echo %GREEN%[OK]%NC% 資料庫類型已設定為: SQLite ^(本地模式^)
|
||
) else (
|
||
REM MySQL 模式: 僅設定 type=mysql,保留連線資訊
|
||
powershell -Command "$config = Get-Content '%CONFIG_FILE%' -Raw | ConvertFrom-Json; $config.backend.database.type = 'mysql'; $json = $config | ConvertTo-Json -Depth 10; [System.IO.File]::WriteAllText('%CONFIG_FILE%', $json, [System.Text.UTF8Encoding]::new($false))"
|
||
echo %GREEN%[OK]%NC% 資料庫類型已設定為: MySQL ^(雲端模式^)
|
||
)
|
||
|
||
if errorlevel 1 (
|
||
echo %RED%[ERROR]%NC% 更新 config.json database.type 失敗
|
||
exit /b 1
|
||
)
|
||
goto :eof
|
||
|
||
:setup_client
|
||
echo %BLUE%[STEP]%NC% 設置前端建置環境...
|
||
|
||
cd /d "%CLIENT_DIR%"
|
||
|
||
REM 總是執行 npm install 確保依賴完整
|
||
echo %BLUE%[INFO]%NC% 安裝前端依賴...
|
||
call npm install
|
||
if errorlevel 1 (
|
||
echo %RED%[ERROR]%NC% npm install 失敗
|
||
exit /b 1
|
||
)
|
||
|
||
REM 確認 electron-builder 已安裝
|
||
if not exist "node_modules\electron-builder" (
|
||
echo %RED%[ERROR]%NC% electron-builder 未安裝
|
||
echo %BLUE%[INFO]%NC% 請檢查 package.json 中的 devDependencies
|
||
exit /b 1
|
||
)
|
||
|
||
if not exist ".env" (
|
||
if exist ".env.example" (
|
||
copy .env.example .env >nul
|
||
echo %YELLOW%[WARN]%NC% 已創建 .env 檔案,請確認設定
|
||
)
|
||
)
|
||
|
||
echo %GREEN%[OK]%NC% 前端建置環境就緒
|
||
goto :eof
|
||
|
||
:build_electron
|
||
echo %BLUE%[STEP]%NC% 打包 Electron 應用...
|
||
|
||
cd /d "%CLIENT_DIR%"
|
||
|
||
REM 驗證 BUILD_TARGET
|
||
if /i "%BUILD_TARGET%"=="nsis" goto :valid_target
|
||
if /i "%BUILD_TARGET%"=="portable" goto :valid_target
|
||
echo %RED%[ERROR]%NC% 無效的打包目標: %BUILD_TARGET%
|
||
echo %BLUE%[INFO]%NC% 有效選項: nsis, portable
|
||
exit /b 1
|
||
|
||
:valid_target
|
||
if /i "%BUILD_TARGET%"=="nsis" (
|
||
echo %BLUE%[INFO]%NC% 目標平台: Windows NSIS 安裝檔 - 推薦
|
||
) else (
|
||
echo %BLUE%[INFO]%NC% 目標平台: Windows Portable
|
||
echo %YELLOW%[WARN]%NC% 注意: Portable 模式的臨時資料夾會在關閉時清空
|
||
echo %YELLOW%[WARN]%NC% SQLite 資料庫已自動儲存到 %%APPDATA%%\Meeting-Assistant
|
||
)
|
||
|
||
REM 清理可能損壞的 electron-builder 快取(解決 symlink 問題)
|
||
set "EB_CACHE=%LOCALAPPDATA%\electron-builder\Cache\winCodeSign"
|
||
if exist "%EB_CACHE%" (
|
||
echo %BLUE%[INFO]%NC% 清理 electron-builder 快取...
|
||
rmdir /s /q "%EB_CACHE%" 2>nul
|
||
)
|
||
|
||
echo %BLUE%[INFO]%NC% 執行 electron-builder...
|
||
|
||
REM 使用 npm run build 或直接執行 node_modules 中的 electron-builder
|
||
if exist "node_modules\.bin\electron-builder.cmd" (
|
||
call "node_modules\.bin\electron-builder.cmd" --win %BUILD_TARGET%
|
||
) else (
|
||
call npx electron-builder --win %BUILD_TARGET%
|
||
)
|
||
|
||
if errorlevel 1 (
|
||
echo %RED%[ERROR]%NC% electron-builder 執行失敗
|
||
echo %YELLOW%[WARN]%NC% 如果出現 symlink 錯誤,請嘗試以下方案:
|
||
echo %YELLOW%[WARN]%NC% 1. 以系統管理員身分執行此腳本
|
||
echo %YELLOW%[WARN]%NC% 2. 或啟用 Windows 開發人員模式(設定 ^> 更新與安全性 ^> 開發人員專用)
|
||
exit /b 1
|
||
)
|
||
|
||
if exist "dist" (
|
||
echo %GREEN%[OK]%NC% Electron 打包完成
|
||
echo %BLUE%[INFO]%NC% 輸出目錄: %CLIENT_DIR%\dist
|
||
) else (
|
||
echo %RED%[ERROR]%NC% Electron 打包失敗 - dist 目錄不存在
|
||
exit /b 1
|
||
)
|
||
goto :eof
|
||
|
||
:finalize_build
|
||
echo %BLUE%[STEP]%NC% 整合建置輸出...
|
||
|
||
if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%"
|
||
|
||
REM 複製 Electron 輸出
|
||
if exist "%CLIENT_DIR%\dist" (
|
||
xcopy /s /e /y "%CLIENT_DIR%\dist\*" "%BUILD_DIR%\" >nul 2>&1
|
||
)
|
||
|
||
echo.
|
||
echo %CYAN%==========================================
|
||
echo 建置完成
|
||
echo ==========================================%NC%
|
||
echo.
|
||
echo 輸出目錄: %BUILD_DIR%
|
||
echo.
|
||
|
||
dir /b "%BUILD_DIR%"
|
||
|
||
echo.
|
||
echo %GREEN%[OK]%NC% 打包完成!
|
||
echo.
|
||
if /i "%BUILD_TARGET%"=="nsis" goto :show_nsis_help
|
||
goto :show_portable_help
|
||
|
||
:show_nsis_help
|
||
echo Windows 使用說明 - NSIS 安裝檔
|
||
echo 1. 找到 build\ 中的 *-setup.exe 檔案
|
||
echo 2. 執行安裝檔,選擇安裝目錄
|
||
echo 3. 安裝後從開始選單或桌面捷徑啟動
|
||
echo 4. 資料會持久保存在安裝目錄中
|
||
goto :end_help
|
||
|
||
:show_portable_help
|
||
echo Windows 使用說明 - Portable
|
||
echo 1. 找到 build\ 中的 *-portable.exe 檔案
|
||
echo 2. 直接執行,無需安裝
|
||
echo 3. 注意 - 關閉程式後臨時檔案會清空
|
||
echo 4. SQLite 資料庫保存在 %%APPDATA%%\Meeting-Assistant
|
||
goto :end_help
|
||
|
||
:end_help
|
||
echo.
|
||
goto :eof
|
||
|
||
:do_build
|
||
call :show_banner
|
||
call :check_environment
|
||
if errorlevel 1 exit /b 1
|
||
|
||
if "%CLEAN_BUILD%"=="true" call :do_clean
|
||
|
||
REM 更新 API URL(如果有指定)
|
||
call :update_config
|
||
|
||
REM 更新 embedded backend 設定(如果有指定)
|
||
call :update_config_embedded
|
||
|
||
REM 內嵌後端模式預設使用 SQLite(除非明確指定 mysql)
|
||
if "%EMBEDDED_BACKEND%"=="true" (
|
||
if "%DATABASE_TYPE%"=="" set "DATABASE_TYPE=sqlite"
|
||
)
|
||
|
||
REM 更新資料庫類型設定
|
||
call :update_config_database
|
||
|
||
if "%SKIP_SIDECAR%"=="false" (
|
||
call :setup_sidecar_venv
|
||
call :build_sidecar
|
||
)
|
||
|
||
if "%SKIP_BACKEND%"=="false" (
|
||
call :setup_backend_venv
|
||
call :build_backend
|
||
)
|
||
|
||
call :setup_client
|
||
call :build_electron
|
||
call :finalize_build
|
||
goto :eof
|
||
|
||
:do_sidecar
|
||
call :show_banner
|
||
call :check_environment
|
||
if errorlevel 1 exit /b 1
|
||
|
||
if "%CLEAN_BUILD%"=="true" (
|
||
if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist"
|
||
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
|
||
)
|
||
|
||
call :setup_sidecar_venv
|
||
call :build_sidecar
|
||
goto :eof
|
||
|
||
:do_electron
|
||
call :show_banner
|
||
call :check_environment
|
||
if errorlevel 1 exit /b 1
|
||
|
||
if not exist "%SIDECAR_DIR%\dist\transcriber" (
|
||
if "%SKIP_SIDECAR%"=="false" (
|
||
echo %YELLOW%[WARN]%NC% Sidecar 尚未打包
|
||
echo %BLUE%[INFO]%NC% 請先執行: %~nx0 sidecar
|
||
echo %BLUE%[INFO]%NC% 或使用 --skip-sidecar 跳過
|
||
exit /b 1
|
||
)
|
||
)
|
||
|
||
if "%CLEAN_BUILD%"=="true" (
|
||
if exist "%CLIENT_DIR%\dist" rmdir /s /q "%CLIENT_DIR%\dist"
|
||
)
|
||
|
||
call :setup_client
|
||
call :build_electron
|
||
call :finalize_build
|
||
goto :eof
|
||
|
||
:show_help
|
||
echo.
|
||
echo Meeting Assistant Client - Windows 打包腳本
|
||
echo.
|
||
echo 用法: %~nx0 [命令] [選項]
|
||
echo.
|
||
echo 命令:
|
||
echo build 完整建置 (Sidecar + Electron)
|
||
echo sidecar 僅打包 Sidecar
|
||
echo electron 僅打包 Electron (需先打包 Sidecar)
|
||
echo clean 清理建置目錄
|
||
echo help 顯示此幫助訊息
|
||
echo.
|
||
echo 選項:
|
||
echo --api-url URL 後端 API URL
|
||
echo --skip-sidecar 跳過 Sidecar 打包
|
||
echo --skip-backend 跳過 Backend 打包
|
||
echo --embedded-backend 打包內嵌後端,預設使用 SQLite
|
||
echo --database-type TYPE 資料庫類型: sqlite 或 mysql
|
||
echo --target TARGET 打包目標: nsis 或 portable
|
||
echo --clean 建置前先清理
|
||
echo.
|
||
echo 範例:
|
||
echo %~nx0 build 完整建置
|
||
echo %~nx0 build --embedded-backend 全包部署,SQLite 本地資料庫
|
||
echo %~nx0 build --embedded-backend --database-type mysql 全包部署,MySQL 雲端
|
||
echo %~nx0 build --target portable 打包為 Portable
|
||
echo %~nx0 sidecar 僅打包 Sidecar
|
||
echo %~nx0 electron --skip-sidecar 僅打包 Electron
|
||
echo.
|
||
echo 部署模式:
|
||
echo 分離部署: 前端連接遠端後端,使用 --api-url 指定後端地址
|
||
echo 全包部署: 使用 --embedded-backend,預設 SQLite 本地資料庫
|
||
echo.
|
||
echo 打包目標:
|
||
echo nsis: 產生安裝檔,推薦正式使用
|
||
echo portable: 產生免安裝 exe,SQLite 資料庫儲存到 %%APPDATA%%
|
||
echo.
|
||
echo 資料庫模式 - 全包部署時:
|
||
echo SQLite 預設: 本地資料庫,完全離線運作
|
||
echo MySQL: 需明確指定 --database-type mysql,連接雲端資料庫
|
||
echo.
|
||
echo 注意:
|
||
echo - 首次打包 Sidecar 需下載 Whisper 模型,可能需要較長時間
|
||
echo - 全包部署需要額外約 50MB 空間用於後端
|
||
echo - 確保有足夠的磁碟空間 (建議 5GB+)
|
||
echo.
|
||
goto :eof
|
||
|
||
:end
|
||
endlocal
|