專案

一般

配置概況

Feature #1365

是由 陳國瑋27 天 前更新

## 目的 

 調整 LINE LIFF 充電樁狀態頁面的 Connector Status UI mapping,讓 FE 能依 websocket / initial API 回傳的 `connectorData.status` 正確呈現狀態、CTA、Label、離峰充電 switch 與排隊行為。 

 此需求目標是 `react/web` 的 LIFF 充電頁,不是 Branch Admin UI。 

 ## 適用畫面 

 - Public charging page:`/charger/{connectorId}` 
 - Private charging page:`/charger/{connectorId}/private` 

 ## 資料來源 

 FE 應使用以下資料來源合併顯示: 

 - Initial API:`GET /api/connector/info/{buildingId}/{connectorId}` 
 - WebSocket connector update 
 - `connectorData.status`:UI 邏輯判斷來源 
 - `connectorData.statusLabel`:中文顯示文字來源 
 - `connectorData.enableOffPeak`:離峰充電 switch 狀態 
 - `connectorData.nextOffPeakTimeStart` 
 - `connectorData.nextOffPeakTimeEnd` 

 `statusLabel` 只作為顯示文字,不應作為 FE 邏輯判斷來源。 

 ## WebSocket URL 與參數 

 FE 應使用環境變數 `NEXT_PUBLIC_CHARGING_WS_URL` 作為 websocket base URL。 

 建議設定值: 

 ```text 
 NEXT_PUBLIC_CHARGING_WS_URL=wss://{hq-api-domain}/ws/connector 
 ``` 

 實際連線 URL: 

 ```text 
 wss://{hq-api-domain}/ws/connector/{buildingId}/{connectorId}?xLineId={lineId} 
 ``` 

 參數說明: 

 | 位置 | 參數 | 必填 | 說明 | 
 |---|---|---|---| 
 | path | `buildingId` | yes | 社區 ID;用於 websocket session routing 與後端驗證住戶是否已綁定該社區。 | 
 | path | `connectorId` | yes | 充電樁 ID;用於訂閱單一 connector 的 initial data 與後續 update。 | 
 | query | `xLineId` | yes | LINE user id。Browser WebSocket 無法自訂 header,因此以 query string 傳遞等效的 `X-Line-ID`。 | 

 FE URL 組法需支援兩種形式: 

 - base URL 形式:`NEXT_PUBLIC_CHARGING_WS_URL=wss://{hq-api-domain}/ws/connector`,FE 自動補上 `/{buildingId}/{connectorId}`。 
 - placeholder 形式:`NEXT_PUBLIC_CHARGING_WS_URL=wss://{hq-api-domain}/ws/connector/{buildingId}/{connectorId}`,FE 直接替換 `{buildingId}` 與 `{connectorId}`。 

 若缺少 `NEXT_PUBLIC_CHARGING_WS_URL`、`buildingId`、`connectorId` 或 `xLineId`,FE 不應建立 websocket 連線,並應進入 error/fallback 狀態。 

 ## Status Mapping 

 | status | statusLabel | UI Tone | 行為 | 
 |---|---|---|---| 
 | AVAILABLE | 待命 | green | 可開始充電;Private 可切換離峰充電 | 
 | ENQUEUED | 排隊中 | blue | Private 顯示離峰排隊狀態與取消排隊 | 
 | PREPARING | 準備中 | orange | 可停止充電;不可切換離峰充電 | 
 | CHARGING | 充電中 | green | 可停止充電;顯示充電資訊 | 
 | SUSPENDEDEVSE | 充電站暫停 | yellow | 可停止充電;不可開始充電;不可切換離峰充電 | 
 | SUSPENDEDEV | 車輛暫停 | yellow | 可停止充電;不可開始充電;不可切換離峰充電 | 
 | FINISHING | 結束中 | yellow | read-only;不可再次充電 | 
 | RESERVED | 已預約 | blue/neutral | read-only;不可開始充電 | 
 | UNAVAILABLE | 不可用 | gray | read-only | 
 | FAULTED | 故障 | red | read-only | 
 | unknown/null | 未知狀態 | gray | read-only;不可 fallback 成 AVAILABLE | 

 ## UI Color Tone 

 請 follow 目前 `react/web` 既有色碼基準: 

 | Tone | 建議色碼 | 
 |---|---| 
 | green | `#00c300` | 
 | red | `#ef4444` | 
 | orange | `#f59e0b` | 
 | yellow | `#facc15` | 
 | blue | `#3b82f6` | 
 | gray | `#9ca3af` | 

 ## CTA 行為 

 Public page: 

 | status | CTA | 
 |---|---| 
 | AVAILABLE | 顯示開始充電 | 
 | PREPARING / CHARGING / SUSPENDEDEVSE / SUSPENDEDEV | 顯示停止充電 | 
 | FINISHING / RESERVED / UNAVAILABLE / FAULTED / unknown/null | 不顯示可操作 CTA,只顯示狀態 | 

 Private page: 

 | status | CTA | 
 |---|---| 
 | AVAILABLE + enableOffPeak=false | 顯示立即充電 | 
 | AVAILABLE + enableOffPeak=true | 立即充電 disabled,因為已啟用離峰充電 | 
 | ENQUEUED | 顯示取消排隊 | 
 | PREPARING / CHARGING / SUSPENDEDEVSE / SUSPENDEDEV | 顯示停止充電 | 
 | FINISHING / RESERVED / UNAVAILABLE / FAULTED / unknown/null | 不顯示可操作 CTA,只顯示狀態 | 

 ## 離峰充電行為 

 Private page 才顯示離峰充電 switch。 

 - 只有 `AVAILABLE` 狀態可以切換離峰充電 switch。 
 - `enableOffPeak=true` 時,不可立即充電。 
 - `ENQUEUED` 時顯示離峰排隊狀態。 
 - `ENQUEUED` 時顯示 `nextOffPeakTimeStart` / `nextOffPeakTimeEnd` 作為離峰時段。 
 - `ENQUEUED` 時提供取消排隊 CTA。 
 - 取消排隊成功後,離峰充電模式應同步呈現為 OFF。 
 - `enableOffPeak` 為 null 或 undefined 時,不可沿用舊 switch 狀態造成 stale UI;應以 disabled/read-only 狀態處理。 

 ## 實作要求 

 - 建立集中式 status metadata / mapping,避免 Public / Private page 各自寫分散判斷。 
 - `status` 是 UI 邏輯判斷來源。 
 - `statusLabel` 是中文顯示來源。 
 - unknown/null status 必須顯示 `未知狀態`,且不可被視為 `AVAILABLE`。 
 - 移除目前 `FINISHING` 可重新開始充電的 UI 行為。 
 - 補齊 `SUSPENDEDEVSE`、`SUSPENDEDEV`、`RESERVED` 的 UI 狀態。 
 - websocket live data 與 initial API data 合併後,畫面應即時更新。 

 ## 驗收條件 

 - LIFF Public / Private Connector Status page 都能正確顯示所有 status。 
 - FE 使用 `NEXT_PUBLIC_CHARGING_WS_URL` 組成 `wss://{hq-api-domain}/ws/connector/{buildingId}/{connectorId}?xLineId={lineId}` 連線。 
 - 缺少 websocket URL、`buildingId`、`connectorId` 或 `xLineId` 時,FE 不建立 websocket 並進入 error/fallback 狀態。 
 - unknown/null status 不會顯示為待命,也不會出現開始充電 CTA。 
 - `FINISHING` 不會顯示開始充電或再次充電 CTA。 
 - Private page 只有 `AVAILABLE` 可切換離峰充電。 
 - `enableOffPeak=true` 時,立即充電不可操作。 
 - `ENQUEUED` 顯示排隊中、離峰時段與取消排隊。 
 - websocket 收到 status update 後,status label、CTA、離峰 switch、排隊資訊會同步更新。 

返回