/** * HR Portal 系統初始化引導頁面 * * 功能: * 1. 檢查系統初始化狀態(三階段:Initialization/Operational/Transition) * 2. 引導用戶完成環境配置 * 3. 顯示當前階段與配置進度 */ 'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' interface SystemStatus { current_phase: 'initialization' | 'operational' | 'transition' is_initialized: boolean initialization_completed: boolean configured_count: number configured_categories: string[] missing_categories: string[] is_locked?: boolean next_action: string message: string // Operational 階段欄位 last_health_check_at?: string health_check_status?: string // Transition 階段欄位 env_db_consistent?: boolean inconsistencies?: string } interface ConfigDetail { redis?: { host: string; port: string; db: string } database?: { host: string; port: string; name: string; user: string } keycloak?: { url: string; realm: string; admin_username: string } } export default function InstallationPage() { const router = useRouter() const [status, setStatus] = useState(null) const [configDetails, setConfigDetails] = useState({}) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { checkSystemStatus() }, []) const checkSystemStatus = async () => { try { setLoading(true) setError(null) const response = await fetch('http://10.1.0.245:10181/api/v1/installation/check-status') if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`) } const data: SystemStatus = await response.json() setStatus(data) // 載入已完成配置的詳細資訊 if (data.configured_categories.length > 0) { await loadConfigDetails(data.configured_categories) } // 如果已初始化,導向健康檢查頁面 if (data.is_initialized) { router.push('/installation/health-check') } } catch (err) { console.error('[Installation] Failed to check status:', err) setError(err instanceof Error ? err.message : '無法連接到後端 API') } finally { setLoading(false) } } const loadConfigDetails = async (categories: string[]) => { const details: ConfigDetail = {} for (const category of categories) { try { const response = await fetch(`http://10.1.0.245:10181/api/v1/installation/get-config/${category}`) if (response.ok) { const data = await response.json() console.log(`[Installation] Loaded ${category} config:`, data) if (data.configured && data.config) { details[category as keyof ConfigDetail] = data.config console.log(`[Installation] ${category} details:`, data.config) } } } catch (error) { console.error(`[Installation] Failed to load ${category} config:`, error) } } console.log('[Installation] All config details:', details) setConfigDetails(details) } const startInstallation = () => { // 導向下一個未完成的設定階段 if (!status) return if (!status.configured_categories.includes('redis')) { router.push('/installation/phase1-redis') } else if (!status.configured_categories.includes('database')) { router.push('/installation/phase2-database') } else if (!status.configured_categories.includes('keycloak')) { router.push('/installation/phase3-keycloak') } } if (loading) { return (

HR Portal 系統初始化

正在檢查系統狀態...

) } if (error) { return (

連接失敗

{error}

可能的原因:

  • 後端服務未啟動 (Port 10181)
  • 資料庫連接失敗
  • 網路連接問題
) } // 階段顏色與圖示(深色主題) const getPhaseConfig = (phase: string) => { switch (phase) { case 'initialization': return { color: 'from-blue-500 to-indigo-600', bgColor: 'bg-blue-900/20', borderColor: 'border-blue-700', textColor: 'text-blue-300', icon: '⚙️', title: 'Initialization 階段', description: '系統初始化中,正在設定環境配置' } case 'operational': return { color: 'from-green-500 to-emerald-600', bgColor: 'bg-green-900/20', borderColor: 'border-green-700', textColor: 'text-green-300', icon: '✅', title: 'Operational 階段', description: '系統正常運作中,可進行健康檢查' } case 'transition': return { color: 'from-orange-500 to-amber-600', bgColor: 'bg-orange-900/20', borderColor: 'border-orange-700', textColor: 'text-orange-300', icon: '🔄', title: 'Transition 階段', description: '系統移轉中,正在檢查環境一致性' } default: return { color: 'from-gray-500 to-gray-600', bgColor: 'bg-gray-800', borderColor: 'border-gray-700', textColor: 'text-gray-300', icon: '❓', title: '未知階段', description: '系統狀態未知' } } } const phaseConfig = status ? getPhaseConfig(status.current_phase) : null return (
{/* Header */}

HR Portal 系統狀態

三階段系統管理

{/* Phase Status Card */} {status && phaseConfig && (
{phaseConfig.icon}

{phaseConfig.title}

{phaseConfig.description}

{/* Message from Backend */}

{status.message}

{/* Configuration Progress */} {status.current_phase === 'initialization' && ( <>
環境配置進度 {status.configured_count} / 3 完成
{[ { key: 'redis', name: 'Redis 快取設定', icon: '🔴', route: '/installation/phase1-redis' }, { key: 'database', name: '資料庫連接設定', icon: '🗄️', route: '/installation/phase2-database' }, { key: 'keycloak', name: 'Keycloak SSO 設定', icon: '🔐', route: '/installation/phase3-keycloak' }, ].map((step) => { const isConfigured = status.configured_categories.includes(step.key) const config = configDetails[step.key as keyof ConfigDetail] // 格式化配置資訊 let configInfo = '' if (config) { if (step.key === 'redis') { configInfo = `${config.host}:${config.port} (DB ${config.db})` } else if (step.key === 'database') { configInfo = `${config.host}:${config.port}/${config.name}` } else if (step.key === 'keycloak') { configInfo = `${config.url} (${config.realm})` } } return (
{step.icon}
{step.name}
{isConfigured && configInfo && (
{configInfo}
)}
{isConfigured ? ( 已完成 ) : ( )}
) })}
{/* Action Buttons */}
{status.missing_categories.length > 0 ? ( ) : ( )} {/* 開發測試:重置按鈕 */} {status.configured_count > 0 && ( )}
)} {/* Operational Phase Actions */} {status.current_phase === 'operational' && (
)} {/* Transition Phase Actions */} {status.current_phase === 'transition' && (
{status.env_db_consistent && ( )}
)}
)} {/* Info Card */} {status && (

{status.current_phase === 'initialization' && '初始化階段說明'} {status.current_phase === 'operational' && '營運階段說明'} {status.current_phase === 'transition' && '移轉階段說明'}

    {status.current_phase === 'initialization' && ( <>
  • 環境配置會同時寫入 .env 檔案和資料庫,確保一致性
  • 每個環境都會進行連線測試,確保設定正確後才會儲存
  • 完成所有環境配置後,才能進入營運階段
  • )} {status.current_phase === 'operational' && ( <>
  • 系統正常運作中,可定期執行健康檢查確保服務穩定
  • 健康檢查會驗證 Redis、Database、Keycloak 等服務狀態
  • 需要進行系統遷移時,請先切換到 Transition 階段
  • )} {status.current_phase === 'transition' && ( <>
  • Transition 階段用於系統遷移或環境變更
  • 請執行一致性檢查,確保 .env 檔案與資料庫配置同步
  • 只有通過一致性檢查後,才能返回營運階段
  • )}
)}
) }