專案

一般

配置概況

Feature #1422

是由 陳國瑋 於 15 天 前更新

## 閱讀方式與需求定位 

 請並排開啟 [HTML Mock v0.3](https://redmine.sylksoft.com/attachments/1117),依下方 **01 → 08** 的順序閱讀:由上到下,同一列由左到右。編號是本 Description 的對照索引,尚未加在 Mock 畫面上。 

 本功能把目前空白的 Branch Admin「Dashboard」做成**唯讀營運總覽**,讓使用者快速看懂設備、供電、充電用量與結算狀態;需要處理事情時,再前往既有管理頁。**不改變充電、輪充、Queue 或帳務作業邏輯。** 

 - 適用所有案場;A17 只是 Mock 展示與首站驗證案例,不能把其名稱、數量或設定寫死。 
 - Mock 中的數字都是假資料,僅用來對照畫面,不是正式驗收的固定數值。 
 - 目前文件套件仍為 **v0.3 Draft**,尚非 v1.0 開發基準。2026-09-14 本次僅重整 Description 的敘述與排版,不發布新版本,也不變更已確認需求。 
 - 第 01~08 節說明畫面;第 09 節集中說明資料更新與異常狀態;第 10~12 節供開發、驗收與版本追蹤。各子票保留完整決策細節。 

 ## 畫面配置與對照圖 

 下圖表示桌面版的區塊位置,不表示各區實際尺寸。左側 Sidebar 是案場識別與導覽;主內容的閱讀順序如下: 

 ```text 
 左側 Sidebar        主內容(由上往下) 
                   ┌─────────────────────────────────────────┐ 
                   │ 01 頁首:案場名稱        連線/更新/刷新      │ 
                   ├─────────────────────────────────────────┤ 
                   │ 02 需留意事項                             │ 
                   ├─────────────────────────────────────────┤ 
                   │ 03 六張 KPI:03-1 → 03-2 → … → 03-6       │ 
                   ├─────────────────────┬───────────────────┤ 
                   │ 04 案場即時負載        │ 05 群組容量         │ 
                   │      目前功率+趨勢      │      與 Slots         │ 
                   ├─────────────────────┴───────────────────┤ 
                   │ 06 Connector 即時狀態                     │ 
                   │      五項摘要 → 預覽卡片 → 查看全部           │ 
                   ├─────────────────────┬───────────────────┤ 
                   │ 07 30 日充電用量       │ 08 結算流程         │ 
                   └─────────────────────┴───────────────────┘ 
 ``` 

 小螢幕依同一內容順序換行;各區的卡片數與欄數依下方規則調整,不以縮小文字或頁面水平捲動容納內容。 

 ## 01|頁首與左側案場識別 

 **要讓使用者知道:目前正在看哪個案場,以及資料是否仍在更新。** 

 對照 Mock 頂部「案場營運總覽」與左側「目前案場」: 

 | 位置 | 顯示內容 | 行為與規則 | 
 |---|---|---| 
 | 左側案場識別、主內容標題下方 | Backend 回傳的案場名稱;Mock 為「寶台 A17・地下停車場」 | 唯讀識別,不是案場切換選單。 | 
 | 頁首右側第一行 | 即時連線正常/無法連線/連線中斷 | 只表示兩個即時區塊的 WebSocket 連線情況,不代表所有設備正常。 | 
 | 頁首右側第二行 | 一般資料最後更新時間 | 對應最近一次 Overview 資料;與即時連線狀態分開顯示。 | 
 | 右側刷新按鈕 | 重新整理一般資料 | 取得一次 Overview,不重建 WebSocket;整頁重新載入才重新嘗試連線。 | 

 **案場範圍:** 每個 EMS Branch 必須恰好有一個 enabled Building,由 Backend 決定本次資料範圍。若零筆或多筆,顯示「案場設定異常」並隱藏營運數字;不可任選第一筆、跨案場加總或填入 0。 

 Sidebar 中其他導覽是 Mock 的展示脈絡,不代表本需求要重新開發這些管理頁;正式版沿用既有選單、路由及權限。 

 **開發對照:** #1424 DEC-029~033。Backend 提供案場識別、時間與狀態;FE 顯示並處理設定錯誤。 

 ## 02|需留意事項 

 **要讓使用者知道:哪些「已確認的狀況」值得進一步查看。** 這是摘要,不是新的告警、派工或自動修復系統。 

 Mock 目前顯示「3 類」:設備故障 1 個 Connector、Queue 阻塞 2 個項目、結算待確認 2 個步驟。**3 是類別數,不是 1+2+2,也不是不同設備總數。** 

 ### 類別、數字與點擊目的地 

 只顯示數量大於 0 的類別,依以下固定順序排列;不依數量、時間或顏色重排。 

 | 順序 | 類別 | 數字代表什麼 | 點擊後 | 
 |---|---|---|---| 
 | 1 | Charge Point 離線 | 既有 OCPP 連線狀態為 OFFLINE 的 CP 數;同一 CP 只計一次 | 既有 /cp/list | 
 | 2 | Connector 故障(Mock 文案「設備故障」) | 既有狀態為 FAULTED 的 Connector 數;同一 Connector 只計一次 | 既有 /connector/list | 
 | 3 | 即時負載資料不完整 | 「目前負載」為 STALE/PARTIAL/ERROR 時算 1 類、受影響數量固定 1 | 同頁 04 案場即時負載 | 
 | 4 | Queue 阻塞 | 既有 BLOCKED Queue 項目數;依 Queue entry ID 去重 | 同頁 06 Connector 即時狀態 | 
 | 5 | 結算未完成/異常(Mock 文案「結算待確認」) | Backend 已確認未完成或異常的結算步驟數 | 同頁 08 結算流程 | 

 - 同一類別內去除重複;不同類別不推論共同原因,也不跨類合併。 
 - 只看「目前負載」的資料品質;歷史圖表的缺口不另外增加此摘要,尚未結束但資料完整的時間區間也不是異常。 
 - CP 離線與尚未結束的充電 Session 分別呈現,不推論「仍在離線充電」或「待 reconciliation」。 
 - 所有非零類別全部顯示。桌面自動換行、平板兩欄、手機單欄;不做 Top N、展開、Drawer 或分頁。 

 ### 正常、部分失敗與全部失敗 

 | 情況 | 使用者看到什麼 | 
 |---|---| 
 | 完整查詢成功,確定 0 類 | 保留精簡狀態列:「目前沒有需留意事項」,附「所有已檢查的狀態目前皆正常」與更新時間。 | 
 | 部分來源失敗 | 顯示已確認的項目,註明「部分狀態暫時無法確認,顯示數量可能不完整」;有項目時標題為「已確認 N 類項目需要留意」。 | 
 | 整體無法取得 | 顯示「需留意事項暫時無法取得」,數量為未知,不顯示 0 類正常。 | 

 每張卡為單一連結,支援滑鼠、Tab 與 Enter。同頁導覽會把焦點移至目標區塊;不自動篩選列表、不新增詳情 API,也不執行任何作業。 

 **開發對照:** #1463 ATT-DEC-001~008;更新方式為第 09 節的共用 REST。 

 ## 03|六張 KPI:由左到右 

 **要讓使用者快速掌握六項營運數字。六張全部使用一般 REST 更新,不訂閱 WebSocket。** 因此可能與下方即時區塊有約 5 分鐘更新差異,這是已接受的 V1 行為。 

 ### 03-A|畫面、含意與操作對照 

 | 編號/Mock 名稱 | Mock 假資料 | 要回答的問題 | 整卡點擊後 | 
 |---|---|---|---| 
 | 03-1 Charge Point 連線 | 4 / 4 台啟用;0 台離線、0 台尚未確認 | 已啟用的 CP 中,有多少目前被系統記錄為在線? | /cp/list | 
 | 03-2 Connector 可服務 | 11 / 12 個;1 個不可服務,其中 1 個故障 | 有多少 Connector 沒有已知故障、不可用或連線問題?**可服務不等於空閒。** | /connector/list | 
 | 03-3 充電進行中 | 3 Sessions | 系統目前有幾筆尚未結束的充電 Session?不保證每筆此刻都正在輸出電力。 | /connector/list | 
 | 03-4 等待供電 | 2 個;另有 1 個未插槍(不計入) | 有多少 Connector 的 Queue 狀態為 ELIGIBLE、正在等候供電? | /connector/list | 
 | 03-5 今日已完成充電量 | 84.6 kWh;已完成 6 次充電 | 歸屬今天、已完成且符合條件的充電,共有多少電量與次數? | 同頁 07 用量區(#usage) | 
 | 03-6 上月電費 | —;8 月結算未完成,10 / 11 筆 | 上一完整日曆月的門牌帳單應收電費總額是多少? | 同頁 08 結算區(#billing) | 

 ### 03-B|Backend 計算與 FE 呈現規則 

 1. **CP 連線:** 分母是本案場 enabled CP;分子使用既有 persisted OCPP ONLINE 狀態。ONLINE+OFFLINE+UNKNOWN=啟用總數。disabled 另列,不算離線;Dashboard 不用 Heartbeat 時間另建連線判定。 
 2. **Connector 可服務:** 分母只含 enabled CP 下的 Connector;分子還必須同時符合 parent CP ONLINE,以及既有狀態為 AVAILABLE、PREPARING、ENQUEUED、CHARGING、SUSPENDED_EV、SUSPENDED_EVSE、FINISHING 或 RESERVED。FAULTED、UNAVAILABLE、未知狀態、parent CP 非 ONLINE 都排除。不可服務=總數-可服務;故障只作「其中」說明,不重複加總。 
 3. **充電進行中:** 每個 Connector 沿用既有 current transaction 解析規則,最多取一筆 canonical ACTIVE transaction(系統認定的目前交易),忽略較舊的孤兒 ACTIVE。Queue 或尚未建立 StartTransaction 的操作不算。CP 暫時離線/停用時,尚未結束的 Session 仍計入,但不推論離線充電。小字固定「依未結束的充電 Session 計算」,不再顯示功率。 
 4. **等待供電:** 只計 ELIGIBLE 的不同 Connector;多筆 Queue 不重複計。NOT_PLUGGED 另列且排除已屬 ELIGIBLE 者,不加回主數字;BLOCKED 放在需留意事項,不新增等待逾時或 SLA。 
 5. **今日已完成充電量:** 直接重用第 07 節 Usage 的今日日期桶(rangeEndDate),不再建立另一套今日查詢;不估算進行中交易、不做昨日同時段比較。交易依**開始日**歸屬,跨日不拆分。 
 6. **上月電費:** Backend 依案場時區取上一完整日曆月,使用該案場 e_bill_settlement.cost_predict;paid/pending 都納入。全部計算 COMPLETE 才回金額,否則回 null,FE 顯示「—」、月份及完成筆數。**不顯示部分合計、不退回更早月份、不做本月預估。** 

 FE 直接呈現 Backend 的聚合結果,不從 Connector 預覽卡重算。第 03-3 的 Session 數與第 06 節的「充電進行中」分類,來源與含意不同,不要求數字相等。 

 ### 03-C|排版與互動 

 | 畫面寬度 | KPI 排列 | 
 |---|---| 
 | ≥ 1240 px | 6 欄 × 1 列 | 
 | 768~1239 px | 3 欄 × 2 列 | 
 | 320~767 px | 2 欄 × 3 列 | 

 固定上述順序,六張完整保留,不用輪播或水平捲動。每張卡是一個原生連結、只有一個 Tab 焦點;Loading/Error 等狀態仍可導覽。長文案換行,數字更新不逐卡朗讀;狀態顯示遵循第 09 節。 

 **開發對照:** #1486 KPI-DEC-001~011;Usage 公式另見 #1461。 

 ## 04|案場即時負載(中段左側) 

 **要讓使用者知道:現在充電功率是多少,以及這段時間的負載如何變化。** 

 由區塊上到下閱讀: 

 1. **右上時間切換:** 即時/今日/7 日;預設「即時」。 
 2. **大數字「目前功率」:** 全案場目前充電功率,單位 kW;Mock 為 21.84 kW。它是目前值,不是整段期間的平均。 
 3. **下方折線圖:** X 軸是案場當地時間;Y 軸是「區間平均總充電功率(kW)」。每個點代表下表的一段時間,不是累計用電量 kWh。 

 | 檢視 | X 軸涵蓋範圍 | 每個點代表的時間區間 | 
 |---|---|---| 
 | 即時 | 最近 60 分鐘 | 1 分鐘 | 
 | 今日 | 案場當地今天 00:00 至現在 | 15 分鐘 | 
 | 7 日 | 含今天的最近 7 個案場日曆日 | 1 小時 | 

 **7 日不是往回推固定 168 小時。** 例如今天是 9/14,日曆範圍從 9/8 00:00 到現在。 

 ### 數值如何取得 

 - Backend 使用有效、未過期的最新電表功率,先統一 W/kW 單位,再建立案場功率時間線。 
 - 圖表採**時間加權平均**:例如一分鐘內前 30 秒為 10 kW、後 30 秒為 20 kW,該點為 15 kW。不能直接把不同頻率、不同時間的 raw MeterValue 列相加或算術平均。 
 - 已確認且資料新鮮的非充電狀態可為 0;充電中的功率超過 cutoff 仍未知時,對應區間為 null+PARTIAL。圖表留缺口,不補 0、不插值、不跨缺口連線,也不只加總已知部分冒充完整總量。 
 - 「時間區間尚在進行中」(OPEN)與「資料是否完整」(COMPLETE/PARTIAL/ERROR)分開表示;OPEN 不等於異常。 

 ### 更新與範圍邊界 

 三組完整歷史資料隨同一次 Overview 回傳,切換頁籤只切換已取得資料,不再發 API 或重建 WebSocket。刷新保留所選頁籤,該頁籤無資料/失敗時不自動跳到別的範圍。 

 WebSocket 只更新目前功率、三種範圍的進行中區間,以及跨界時剛結束的區間;FE 依 buildingId+rangeCode+bucketStartAt 取代對應資料,不自行積分或平均。 

 **本區不顯示案場契約容量、容量利用率或剩餘容量。** 不得把各 Charge Group 的契約容量加總,當作案場契約容量。 

 **開發對照:** #1462 LOAD-DEC-001~007;斷線處理見第 09 節。 

 ## 05|群組容量與 Slots(中段右側) 

 **要讓使用者知道:各充電群組目前的負載、群組自身容量,以及供電名額占用情形。** 

 Mock 依序列出 B1、B2、B3 三個 Charge Group;這些名稱與數量只是範例,正式版依 Backend 資料顯示,不固定三組。 

 | 由上到下的位置 | 內容與意義 | 
 |---|---| 
 | 區塊右上 | 既有時段資訊,例如 Mock 的「離峰時段」。 | 
 | 每個群組標題列 | 群組名稱、目前功率/該群組自身契約容量,單位 kW;例如 B1 的 7.33 / 99 kW。 | 
 | 群組容量條與說明 | 該群組自身容量/餘裕,以及目前充電、等待或 BLOCKED 情況。 | 
 | 群組 Slots | 已占用名額/可配置名額;例如 1 / 14 Slots。Slots 是既有供電名額概念,不是電量。 | 
 | 區塊底部 | OCCUPIED(已占用)、WAITING(等待)、RESERVED(保留)摘要;Mock 為 3/3/0。 | 

 Backend 沿用既有 SlotCalculator、群組容量與 Queue 狀態語意彙整 occupied/reserved/available slots;等待資訊可含 source、status、priority、statusReason、waitingSince/持續時間。只讀取和顯示,**不更改名額分配、輪充派送、優先序或等待門檻**。 

 本區使用一般 REST 更新,不跟著 WebSocket 每次變動;因此不要求與第 04 節的即時功率在每一刻完全同步。 

 **開發對照:** #1462(負載/群組)與 #1424(資料取得)。 

 ## 06|Connector 即時狀態(中下段、整列) 

 **要讓使用者知道:有哪些 Connector,哪些值得先查看,以及個別設備的連線、運作與排隊狀態。** 

 依畫面順序:**區塊標題與資料時間 → 五項摘要 → Connector 預覽卡 → 顯示筆數/查看全部**。 

 ### 06-A|五個狀態摘要:純資訊、不可點擊 

 | 固定順序 | 固定顯示名稱 | Backend code | 
 |---|---|---| 
 | 1 | 需留意 | NEEDS_ATTENTION | 
 | 2 | 充電進行中 | CHARGING | 
 | 3 | 準備/排隊 | WAITING | 
 | 4 | 可用 | AVAILABLE | 
 | 5 | 其他狀態 | OTHER | 

 Backend 對完整集合分類,每個 Connector 由上到下命中第一類,**只屬於一類,五類相加必須等於總數**;需留意數=abnormalTotal。Unknown/資料不足歸「需留意」,NOT_PLUGGED 歸「其他狀態」。完整條件沿用 #1423 UI-DEC-015。 

 - 有 Connector 時固定顯示五項,包括 0,不隨更新隱藏或重排。 
 - 總數 0 時隱藏五項摘要,顯示 Connector 空狀態。 
 - 五項均不可點擊、不進入 Tab 順序、不開 Drawer、不套篩選、不導頁,也不發 request。 
 - FE 使用 Backend 的完整統計,不從畫面上少數預覽卡計算。 

 ### 06-B|預覽卡:少量不撐滿,大量保留總覽 

 Backend 對完整集合依已確認的優先順序與穩定的同順位排序產生**最多前 8 筆**,一起回傳 total、abnormalTotal 及每筆異常原因。FE 不重排、不自行判斷異常,也不把螢幕寬度送給 Backend。 

 | 畫面寬度 | 最多顯示卡片數 | 若案場只有 1 或 2 個 | 
 |---|---|---| 
 | ≥ 1240 px | 8 | 只顯示實際 1/2 張,不補空卡、不把假資料補滿。 | 
 | 640~1239 px | 6 | 同左,按可用寬度排列。 | 
 | < 640 px | 4 | 同左,維持可讀的卡片排列。 | 

 例如 30 個 Connector 的桌面版顯示前 8 張,註明「顯示 8 / 30,另有 22 個未顯示」,由「查看全部」進入完整清單;手機顯示前 4 張。隱藏異常數使用 Backend 異常總數扣除可見異常數,不把未顯示者當成正常。 

 每張卡保留 Connector/Charge Point 識別、位置/類型及已有的功率、Queue 等資訊;以下狀態必須分層,不合成一個「在線/離線」: 

 ```text 
 同一個 Connector 
   ├─ 所屬 CP 的 OCPP 連線:ONLINE/OFFLINE/UNKNOWN 
   ├─ Connector 運作狀態:AVAILABLE/CHARGING/FAULTED… 
   └─ Queue 狀態與原因:ELIGIBLE/BLOCKED/NOT_PLUGGED… 
 ``` 

 Heartbeat/BootNotification 不能把 FAULTED 或 CHARGING 覆寫成 AVAILABLE;Connector runtime 以既有 StatusNotification 為主要來源。未知功率顯示「—」,不是 0。 

 點預覽卡開啟單支詳情,再依既有入口前往管理頁/Engineer Tools;目的頁仍需原有權限,Dashboard 不授予操作能力。 

 ### 06-C|「查看全部」:完整清單 Drawer 

 **Drawer 不是另一個頁面,而是覆蓋在目前 Dashboard 上、從右側滑出的暫時面板。** 桌面保留一部分 Dashboard 作為背景脈絡;平板與手機可改為全螢幕 Sheet。關閉後回到原本 Dashboard 位置,不會把使用者帶離本頁。 

 本區有兩種用途不同的 Drawer,不能混成同一個資料流程: 

 | 入口 | 開啟內容 | 用途 | 
 |---|---|---| 
 | 點一張 Connector 預覽卡 | 單支 Connector 詳情 Drawer | 查看該 Connector 的詳細資訊。 | 
 | 點「查看全部」 | Full List Drawer | 搜尋、篩選及分頁瀏覽目前案場的完整 Connector 清單。 | 

 Full List Drawer 支援搜尋(Connector 是從側邊開啟的完整清單,支援搜尋(Connector ID、Charge Point ID、車位)、「摘要分類」與 ID、車位)、狀態與 Charge Group 篩選。「摘要分類」固定提供:**全部、需留意、充電進行中、準備/排隊、可用、其他狀態**。首頁五項摘要仍是純資訊,不可點擊,也不會替 Drawer 預先套用條件。 篩選。 

 ```text 
 目前 Dashboard 
       │ 點「查看全部」 
       ▼ 查看全部 
    ↓ 
 ┌─ 右側 Full List Drawer ─────────────┐ 
 │ 搜尋 [                      ]            │ 
 │ 摘要分類 [全部 ▼]    Charge Group [▼] │ 
 │ 完整清單:固定優先排序、每頁 搜尋/篩選完整資料集 → Backend 固定優先排序 → 每頁 20 筆      │ 
 │ 
                                                 ↓ 
                                     上一頁/下一頁、頁次/總筆數            │ 
 └─ 關閉後回到原 Dashboard ────────────┘ 
 ``` 

 - 正式版使用/擴充既有 POST /api/connector/search,size 固定 20,sortMode 固定 DASHBOARD_PRIORITY;沿用 page 與 Spring Page 回應格式。 
 - 「摘要分類」使用穩定的 `displayBucket` 條件;未傳代表「全部」,可傳 NEEDS_ATTENTION/CHARGING/WAITING/AVAILABLE/OTHER。 
 - V1 不把 Connector runtime status 與 Queue status 混成另一組篩選選項;既有管理頁的原始 `status` 篩選維持不變。 
 - 先對**完整資料集**搜尋與篩選,再排序、分頁;不能只過濾已下載的 8 張卡或當頁資料。 
 - 0~20 筆不顯示換頁控制;30 筆為 2 頁、100 筆為 5 頁。改搜尋/篩選時回第 1 頁。 
 - 關閉再開保留搜尋、篩選及頁碼;重新載入或離開 Dashboard 後返回則重設。只存在本次頁面記憶體,不存 URL、瀏覽器儲存或 Backend 偏好。 
 - 不提供排序控制、每頁筆數選單、直接跳頁、Grid/Table 切換或 virtualization;不透過 WebSocket 推送完整清單。既有 /connector/list 的排序不變。 

 **開發對照:** #1423 UI-DEC-006~021、#1424 DEC-034~043。預覽區塊由 UI-DEC-006~020、#1424 DEC-034~041。預覽區塊由 WebSocket 整包取代;完整清單仍走 REST。 

 ## 07|30 日充電用量(底部左側) 

 **要讓使用者知道:最近 30 天完成了多少充電、每天分布如何,以及每次平均充多少電。** 

 區塊固定最近 **30 個案場日曆日(含今天)**,保留右上的 kWh/Sessions 切換;不提供 7/90 日或自訂範圍。 

 ### 圖表與右側三項摘要 

 | 位置 | 資訊 | 定義 | 
 |---|---|---| 
 | 圖表 X 軸 | 日期 | 依案場時區,固定 30 個每日資料桶。 | 
 | kWh 模式 Y 軸 | 每日有效充電量(kWh) | 當日符合條件、已完成交易的最終電量合計。 | 
 | Sessions 模式 Y 軸 | 每日有效充電次數(次) | 當日 COMPLETED 且 energy_consumed > 0 的交易筆數。 | 
 | 右側第 1 項 | 有效充電量 | 30 日有效電量合計;Mock 2213.6 kWh。 | 
 | 右側第 2 項 | 充電 Sessions | 30 日有效次數;Mock 136。 | 
 | 右側第 3 項 | 平均每次充電量 | 有效充電量 ÷ 有效次數,由 Backend 計算;Mock 16.28 kWh/次。 | 

 ### 日期歸屬與資料來源 

 ```text 
 9/13 23:30 開始 ──── 跨午夜 ──── 9/14 01:00 結束 
                                   ↓ 
                      完成後,整筆歸入 9/13 
                      不拆成 9/13 與 9/14 兩筆 
 ``` 

 - 只使用 completed transaction 已有的最終 energy_consumed,按既有單位換算 kWh,以 start_timestamp 判斷歸屬日。 
 - ACTIVE 不估算;0 Wh 不算有效 Session;異常 Completed 排除並標示 PARTIAL。 
 - 不讀 raw MeterValue 重算用量、不呼叫 MeterValueTariffCalculationService,也不按費率時段或帳務邊界切分。 
 - 查詢成功但某日無使用,該日為 0;未知為 null。30 日全無使用時,顯示 0 kWh/0 次/—,並提示沒有紀錄,不建立告警。 
 - 平均每次充電量在 0 次時回 null,不除以零。 
 - 初次失敗顯示 Error;刷新失敗可保留同案場最後成功資料與時間,標示失敗/過期,不冒充新資料。 

 **時間使用率已移除**,不再實作其分母、門檻或資料查詢。Usage 與第 04 節 Live Load 是不同資料來源與公式。 

 **開發對照:** #1461 USG-DEC-001~010;更新方式為共用 REST。 

 ## 08|結算流程(底部右側) 

 **要讓使用者知道:最近有結算資料的那一期,四個步驟分別完成到哪裡。** 沿用 Mock 的四列流程,不改成「本月帳務摘要」。 

 Mock 標題為「8 月結算流程」。正式版月份由 Backend 依**最近結算資料**回傳 periodYear/periodMonth/timezone,FE 只格式化,不自行用今天推算。 

 | 由上到下 | 使用者看到的內容 | Mock 假資料 | 
 |---|---|---| 
 | 1. Connector 結算 | 設備電量與費率計算的完成狀態 | 11 / 12 | 
 | 2. 門牌結算 | 私人與公用費用歸戶的完成狀態 | 10 / 11 | 
 | 3. 帳務覆核 | 既有帳務 paid/pending 分布與覆核狀態 | 7 paid、4 pending;進行中 | 
 | 4. 發票結算 | 既有發票結算狀態 | draft;未完成 | 

 四列均為**純資訊、不可點擊**,不在 Dashboard 執行計算、重跑、覆核、請款或開立發票。既有 Backend aggregation/DTO 只讀取狀態,不改月結排程。 

 **與 Mock 的一項差異要明列:** #1460 BIL-DEC-003 已確認區塊 footer 應提供「查看帳單」→ /bill/list、「查看請款/發票」→ /invoice/list;但附件 #1117 的本區尚未畫出這兩個入口。這是既有需求與 Mock 的呈現差異,不是本次新增功能,也不能誤稱 v0.3 已經有畫。 

 **別與 03-6「上月電費」混淆:** 

 | | 03-6 上月電費 | 08 結算流程 | 
 |---|---|---| 
 | 目的 | 看應收電費金額 | 看四步驟的完成狀態 | 
 | 期間 | 上一完整日曆月 | 最近有結算資料的期間 | 
 | 期間是否一定相同 | 不一定 | 不一定 | 
 | 不完整時 | 不顯示部分金額,保留完成筆數 | 各列呈現實際狀態 | 

 **開發對照:** #1460 BIL-DEC-001~003;更新方式為共用 REST。 

 ## 09|共用規則:資料更新、異常與權限 

 ### 09-A|只保留兩條清楚的資料路徑 

 ```text 
 首載/每 5 分鐘/手動刷新 
             │ 
             ▼ 
 GET /api/dashboard/overview 
             ├─ 六張 KPI、需留意事項 
             ├─ 群組容量/Slots、30 日用量 
             ├─ 結算流程、上月電費 
             └─ 負載三組完整歷史;首載另提供即時區初始畫面 

 一條 Dashboard WebSocket 
             ├─ Connector 即時狀態:整個預覽區塊取代 
             └─ 案場即時負載:目前值+進行中/剛結束的區間 
 ``` 

 每次一般更新只呼叫一次 Overview,共用一個 5 分鐘週期,不為各區另設 timer 或 API。六張 KPI 不訂閱 NETWORK_HEALTH_UPDATED/CONNECTOR_OVERVIEW_UPDATED;不影響其他既有功能使用同名事件。 

 WebSocket 最小 message type 固定為 DASHBOARD_LIVE_SNAPSHOT、CONNECTOR_LIVE_BLOCK_UPDATED、LIVE_LOAD_UPDATED。WebSocket 接手後,後續 REST 刷新可更新一般資料與歷史,但**不能覆寫兩區的 live state,也不能在斷線時充當即時備援**。 

 ### 09-B|WebSocket 連不到,明確提示即可 

 | 連線情況 | FE 行為 | 
 |---|---| 
 | 正常 | 更新兩個即時區塊,顯示連線狀態與資料時間。 | 
 | 首次連線失敗 | 頁首與兩區提示無法連線;已有初始資料則保留並標示未即時更新,無資料顯示「—」。 | 
 | 連上後中斷 | 保留最後資料與最後更新時間,明示「已停止更新」。其他 REST 區塊照常更新。 | 

 **不做 REST polling 備援、自訂 backoff/jitter、背景自動重連、sequence/gap recovery、固定 5 秒 coalescing、2 秒傳播 SLO 或專用 Retry 流程。** 使用者重新載入整頁才再建立連線;手動刷新一般資料不重連。 

 以上 DEC-031/032 取代早期較複雜的傳輸提案;不改資料公式或作業流程。 

 ### 09-C|狀態字典:0、未知、失敗不可混用 

 | 狀態 | 中文含意與呈現 | 
 |---|---| 
 | Loading | 還在取得資料,顯示載入樣式,不先填 0。 | 
 | COMPLETE+0 | 確認成功且數量為零;依各區規則顯示 0 或空狀態。 | 
 | PARTIAL | 只有部分資料可確認;保留可信結果並標明不完整,不能宣稱整體正常。 | 
 | ERROR | 該來源無法取得;未知數值為 null/「—」,不轉成 0。 | 
 | 刷新失敗、有舊資料 | 只保留同 building 最後成功資料,顯示 lastSuccessfulAt 與失敗提示,不假裝更新成功。 | 
 | STALE | 資料已過期,顯示過期與時間;不可當成正常即時數據,也不可納入需要即時性的完整總功率。 | 

 Backend 回傳 generatedAt、來源 updatedAt、dataStatus、freshness 及必要的 lastSuccessfulAt。單一子查詢失敗只影響相依區塊,其餘繼續顯示,整體標示 PARTIAL。 

 資料過期 cutoff 由 Backend **依來源設定全系統共用預設值**,所有案場共用;FE 不硬編碼秒數。不做 per-building override、設定資料表、設定 API/UI、權限或 audit trail;A17 僅驗證預設值。 

 未知 code 不當成 AVAILABLE/正常。FE 以 code 判斷、中文 label 顯示;所有狀態須有文字或圖示,不只靠顏色。Production API 失敗絕不能改用 Mock 假資料。 

 ### 09-D|權限與案場隔離 

 - 沿用既有 SS3A dashboard function:administrator、power_user、association、dealer 四個 role 的 Dashboard 內容與唯讀能力一致,不新增 role/function。 
 - 僅有 adm_user、member、hq 或 engineer,且未取得 dashboard function 時,Overview/ticket API 回 403;多 role 使用者具允許權限時可存取。 
 - FE 選單/路由與 Backend function 一致,未授權不得先載入或短暫顯示資料;隱藏選單不能取代 API/ticket 授權。 
 - Overview request、ticket request、WebSocket URL 不帶 FE 指定的 buildingId。Backend 解析唯一 enabled Building,response、ticket binding 與 event envelope 帶相同 buildingId;不符案場的事件不得套用,快取不得跨案場。 
 - Deep link 沿用目的頁權限,不因可看 Dashboard 就可執行 Start/Stop、Reset、Queue、帳務或 Engineer command。 

 **開發對照:** #1424 DEC-028~042。此區集中承接各畫面的共用規則,不另增作業功能。 

 ## 10|開發工作分工與子票索引 

 畫面改動由 FE 負責,但**正式資料聚合、API、WebSocket、權限與驗證也在本需求範圍內**,不能只完成靜態畫面。 

 | 工作 | 需要交付的內容 | 
 |---|---| 
 | Backend/API | DashboardController、DashboardService、typed Overview 與各區 DTO;唯一 Building resolver;依 02~08 節建立唯讀聚合。 | 
 | Backend/Connector | 共用預覽排序與分類 service、Top-8/完整統計;補齊既有 search DTO/query 的 `displayBucket`、搜尋、Charge Group、DASHBOARD_PRIORITY 與固定分頁,不影響管理頁原始 status/排序。 的搜尋條件、DASHBOARD_PRIORITY 與固定分頁,不影響管理頁原排序。 | 
 | Backend/WebSocket | 一條案場 Dashboard socket、ticket 授權、三種最小事件;Connector 區塊取代、負載目前值與區間更新。 | 
 | Backend/權限文件 | Overview/ticket 對應既有 dashboard function;冪等 migration 確認 role-function mapping,Java 不硬編碼 role 名稱;重啟後驗證授權快取。補 OpenAPI @Schema、method/DTO 欄位註解與 contract tests。 | 
 | FE | 實作 react/branch/app/(dashboard)/dashboard/page.tsx、OpenAPI types 與 React Query overview hook;依畫面順序完成元件、圖表、Drawer、狀態、RWD、鍵盤操作與固定導覽。 | 
 | DB/效能 | 優先唯讀聚合,避免 N+1、無界查詢及重複聚合;先量測,必要時才提出 query 或普通 index 優化。 | 
 | QA/發布 | Backend repository/service/security/contract tests,FE fixture/互動/RWD,首站 E2E、效能 baseline、發布 smoke 與下一工作日檢查。 | 

 DB 不新增 Dashboard snapshot table、專用 cache、效能排程、UNIQUE/FOREIGN KEY/CHECK/cascade constraint。不得為本 Dashboard 改動 Queue lifecycle、priority、Slot allocation、Rotation dispatch、OCPP command、月結/費率作業。 

 ### 查閱細節時,直接找對應子票 

 | 子票 | 對應本文 | 已確認決策 | 
 |---|---|---| 
 | #1423 Connector UI/UX | 06 | UI-DEC-006~021(其餘既有 UI-DEC-006~020(其餘既有 UI 決策沿用) | 
 | #1424 REST/WebSocket 與共用規則 | 01、09、10 | DEC-028~043;較早未被取代的技術條件仍見子票 DEC-028~042;較早未被取代的技術條件仍見子票 | 
 | #1463 需留意事項 | 02 | ATT-DEC-001~008 | 
 | #1486 KPI | 03 | KPI-DEC-001~011 | 
 | #1462 Live Load/群組 | 04、05 | LOAD-DEC-001~007 | 
 | #1461 充電用量 | 07、03-5 | USG-DEC-001~010 | 
 | #1460 結算流程 | 08 | BIL-DEC-001~003 | 

 本次把散落的已確認決策併回所屬區塊,不再把已確認內容列在「待決策」底下。子票仍保留完整欄位、排序、狀態與驗收細節;本次不改子票內容、指派或進度。 

 ## 11|驗收、效能與完成條件 

 ### 11-A|依畫面走一次的驗收重點 

 | 對照區塊 | 必須驗證 | 
 |---|---| 
 | 01 頁首 | 唯一/零筆/多筆 enabled Building;案場名稱與隔離;即時連線與一般更新時間分開。 | 
 | 02 需留意 | N 類不是受影響數量總和;固定順序、全部非零項目、類內去重;正常/PARTIAL/ERROR;五類導覽正確,不推論離線充電。 | 
 | 03 KPI | 分子分母、canonical ACTIVE、ELIGIBLE/NOT_PLUGGED 互斥、開始日歸屬、上月全部 COMPLETE 才顯示金額;六卡全 REST、單一連結與正確欄數。 | 
 | 04 負載 | 即時/今日/7 日、X/Y 軸與時間加權;0 與 null 缺口;OPEN/FINALIZED 與品質分開;切換不發 API,斷線不備援。 | 
 | 05 群組 | 群組自身容量、Slots 與既有 Queue 語意;不把群組容量加總成案場契約容量。 | 
 | 06 Connector | 0/1/2/8/9/30/100 筆;五類互斥、加總等於 total、需留意=abnormalTotal,五摘要不可點;Top-8 的 8/6/4 截取與隱藏數量;Drawer 的「摘要分類」對應 displayBucket,搜尋完整集合、排序後每頁 搜尋完整集合、排序後每頁 20、開關保留/reload 重設。 | 
 | 07 用量 | 30 個日期桶、開始日跨日歸屬、只用已完成最終電量、正電量有效次數、平均值;全零/未知/部分失敗與舊資料保留。 | 
 | 08 結算 | 最近資料期間與四步驟狀態、純資訊列、兩個既有列表入口;不誤當上月金額或本月預估。 | 
 | 共用 | 四個允許 role/未授權 403、多 role、無效 ticket 拒絕 WS;null/0/unknown/large value;來源失敗隔離、同案場快取;production 無 fixture fallback。 | 

 - 檢查 390/768/1024/1440 px 及各 breakpoint 臨界值,320 px 以上不產生頁面級水平捲軸。 
 - 狀態、文字對比、focus 與鍵盤符合 WCAG 2.2 AA 基本要求;同頁導覽轉移焦點、支援 reduced motion,更新不逐卡 live announce。 
 - Fixture 包含 Healthy/Critical/Partial/Stale/Empty/Large;KPI 載入、有效零、初次失敗、刷新失敗;WebSocket 正常、首次失敗、連線後中斷。 
 - A17 staging E2E 覆蓋 offline、faulted、active transaction、stale meter、blocked queue、billing、partial data、403,並確認既有管理頁與 Connector 排序無回歸。 

 ### 11-B|實作前資料檢查與效能 baseline 

 以 A17 或具代表性等量資料做唯讀檢查,不把 Mock 數字當結果: 

 - CP ONLINE/OFFLINE/UNKNOWN、runtime;Connector status/area/type 分布。 
 - Active transaction 數與最長持續時間;各群組 contract/allocated/reserved/queue。 
 - MeterValue 24 小時筆數、峰值與最新資料延遲;近 30 日 transaction/kWh/每日分布。 
 - 最近結算資料期間的 Billing/Invoice 狀態;主要資料表筆數/分布及各 aggregate query 的 EXPLAIN。 

 Overview endpoint 記錄 P50/P95 baseline,附環境、資料量/分布、暖機、併發數、sample size 與量測起訖邊界。**V1 不承諾固定 P95 < 1.5 秒 SLA**;只有實測影響正常使用時才提出查詢/普通 index 優化,不預先增加架構。(PERF-DEC-001/DEC-042) 

 ### 11-C|E2E 與發布 

 功能實作的 E2E impact 為 **Add**;本次純 Description 整理為 **No catalog change**,不代表功能已完成或已通過測試。 

 | 優先級 | 長期案例範圍 | 執行 trigger | 
 |---|---|---| 
 | P0 | Overview/ticket/WS 未授權拒絕、PARTIAL、stale safety | Standard、Major、A17 release;適用時為發布阻擋條件 | 
 | P1 | 四 role 正向、多 role、案場 scope、offline/faulted/active/Queue/billing/responsive | Standard、Major、A17 release | 
 | P2 | 大量資料、未知 enum、效能 baseline | Major、A17 release | 

 實作階段依 maintain-ems-e2e-catalog 確認 Case ID 與 release pack;run-specific 結果放 test_report,不放長期 Catalog,Skip 不視為 Pass。 

 首站部署後做一次 smoke test(頁面/Overview/兩區連線或失敗提示/既有頁面),下一個工作日使用既有 application log、維運工具及 DB 負載資訊檢查。發現問題沿用既有 release/rollback 流程;不新增專用監控平台、metrics、instrumentation、自動告警、排程或 24 小時值守。(REL-DEC-001) 

 ### 11-D|Definition of Done 

 - [ ] Product 確認各區數字定義、範圍,完成整體一致性 review。 
 - [ ] Backend API、OpenAPI、SS3A mapping 與測試完成。 
 - [ ] FE 各區、狀態、RWD、accessibility、deep link 完成。 
 - [ ] 首站或代表性資料的 EXPLAIN/P50/P95 baseline 完成;必要優化完成。 
 - [ ] A17 staging E2E 完成,結果與限制已記錄。 
 - [ ] E2E Catalog 與 ai/02-backend-services.md、ai/03-database.md、ai/04-frontend.md 更新。 
 - [ ] 首站 smoke test 與下一工作日既有 log/DB 負載檢查完成。 

 ## 12|文件版號與 Redmine 附件管理(DOC-DEC-001) 

 PDF、Markdown、HTML Mock 是同一套 review 文件,**三份版號必須一致,每一版都新增到 #1422,不覆蓋、不刪除舊附件。** 

 ### 已發布版本索引 

 | 版本/日期 | PDF | Markdown | HTML Mock | 定位 | 
 |---|---|---|---|---| 
 | v0.2 Draft/2026-07-25 | [#1108](https://redmine.sylksoft.com/attachments/1108) | [#1109](https://redmine.sylksoft.com/attachments/1109) | [#1110](https://redmine.sylksoft.com/attachments/1110) | 初版快照;後續多項決策已取代部分內容,不可單獨當現行規格。 | 
 | v0.3 Draft/2026-09-07 | [#1115](https://redmine.sylksoft.com/attachments/1115) | [#1116](https://redmine.sylksoft.com/attachments/1116) | [#1117](https://redmine.sylksoft.com/attachments/1117) | 目前 review 快照,整併發布前已確認需求;尚非 v1.0。 | 

 ### 後續版本規則 

 - **v0.x Draft:** 討論階段快照。Redmine 決策與工作 Mock 可持續演進,到 review checkpoint 才一起發布下一套。 
 - **v1.0:** 所有需求確認、整體一致性檢查與 Product review 完成後的開發基準;不可預先稱 v0.x 為最終文件。 
 - **v1.x:** 不改主要範圍的澄清/文件修正;重大 scope/contract 改變須先在 Redmine 建立新決策,再決定 major version。 
 - 三份封面/頁首、檔名、日期、版號及本索引一致。每版 note 記錄 decision cutoff、變更摘要與三個 attachment IDs。 
 - 檔名固定為 backend-admin-dashboard-requirements-v{version}.pdf、同名 .md,以及 backend-admin-dashboard-mock-v{version}.html;舊 v0.2 不回溯更名。 
 - 有新決策時下一 checkpoint 可發布 v0.4 Draft;全部確認後才發布 v1.0。版本索引只新增列,舊附件永久保留。 
 - v1.0 前以本票及子票的**現行 Description/較新已確認決策**為需求依據;附件是當時的 review 快照,差異須明確標示。 

 **本次編輯紀錄(2026-09-14):** 依附件 #1117 的實際畫面順序重整 Description,加入區塊配置、狀態分層、日期歸屬與資料流示意;把已確認決策移回對應區塊,保留開發、驗收及版本管理內容。未更動既有附件、議題進度或產品範圍。 

 **決策補充(2026-09-16):** Full List Drawer 的篩選正式命名為「摘要分類」,直接使用首頁同一套 displayBucket;首頁五項摘要仍不可點擊,V1 不另建混合 runtime/Queue status 篩選。同步補上 Drawer 定義、Full List 最小 request/response 契約與驗收條件;本輪不發布新附件。 

返回