When --embedded-backend is specified, SQLite is now the default database type instead of MySQL. This is the expected behavior for all-in-one deployment where the app should work offline without external database. Users can still explicitly specify --database-type mysql if needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
623 lines
20 KiB
Batchfile
623 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 ^
|
||
--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
|