這是重新逐張稽核的誠實結果:每張讀 Swift 原始碼當基準,跟現行 Flutter render(下圖)逐項比對。
🟢 = 與 Swift 對齊,🟡 = 只剩顏色/間距/字串/圖示等細節小差,🔴 = 缺整個區塊/分頁/功能。
2026-06-22:修完全部 24 個🔴大缺 + 跑三輪小差修補,每步重截+重稽核。
目前 🔴 大缺 0。剩 🟡 多為 SF Symbol↔Material icon 形狀等平台本質細節。
🟢 對齊 106🟡 小差 29🔴 大缺 0共 135 張
① 登入 / 選餐廳 🟢0 🟡2 🔴0
🟡 小差登入頁
login
Swift:SignInView: background gradient (background→secondary.opacity(0.3)), header (fork.knife.circle.fill or logo image up to 220x220 + 'ChefsMate' largeTitle bold + optional welcomeMessage subheadline), 3 OAuth buttons (Apple black / Google / LINE green), divider '或' + collapsed email link OR 3-step emai
缺口 2 項
Logo not visible in gallery render: assets/login_logo.png is not bundled in the gallery build, and the fallback ShaderMask+Icons.restaurant_menu also fails to render, leaving a large blank space in the top half. Code fallback path is correct. Swift shows fork.knife.circle.fill with primary gradient clearly.
Subtitle '智慧點餐系統' is hardcoded in the Flutter header (always visible). Swift only shows the subtitle when the optional welcomeMessage param is provided. Minor divergence; in production the param will be passed in.
🟡 小差選擇餐廳(active / 審核中 / 停權)
restaurant-select
Swift:WorkspaceSwitcherView: NavigationStack inline title '選擇餐廳', 完成 top-right; ScrollView+LazyVStack spacing 12 / horizontal padding 16 / top padding 16; each card HStack spacing 14 — 44×44 icon (cornerRadius 12, primary fill if selected else primary.opacity(0.12)), name (headline) + subtitle (caption),
缺口 1 項
Flutter uses StitchColors.borderLight for non-selected card border; Swift uses StitchColors.border. Both tokens are subtle gray separators — functionally equivalent but the lighter token may produce a barely-visible border in some themes.
Swift:Full-screen black-50% overlay. Mic indicator: outer pulse circle 120pt blue-20% + inner 80pt blue-30% + mic icon 36pt (mic.fill/mic.slash.fill). HStack: mic left, right column with status label (正在聆聽.../辨識完成 caption white-70%) + transcript (title3 medium white, placeholder '請說出控單指令'). Conditional co
Swift:DailyCloseEditSheet: NavigationStack + Form with (1) 關帳基本資訊 section (readonly info rows: date/closedBy/time/type/expectedCash/actualCash/diff(colored)/startingCash — some optional), (2) lockSection OR 可編輯欄位 section (5 editable rows: blue icon + field name + current value + pencil.circle.fill trailin
缺口 2 項
Edit field sub-sheet (原值 / 新值 / 修改理由(必填)sections with 取消/確認 toolbar and ProgressView) is not implemented in the Flutter gallery view. Expected for a pure-display gallery widget, but worth noting for functional completeness.
Swift conditionally shows closedBy, actualCash, cashDifference, and startingCashResetAmount rows only when non-nil. Flutter hardcodes them as always-present required params with no optional display logic.
Swift:4 sections: (1) 日期範圍 card — 4-option segmented picker (今日/本週/本月/自訂), optional custom date fields, date range text; (2) 資料類型 card — header + 全選/取消全選, 6 type rows (checkbox + icon + name/description), dividers, disabled state for types without local data source; (3) 匯出格式 card — radio button tiles (CSV
缺口 0 項
(無差異)
🟢 對齊資料健康檢查
reports-data-health
Swift:資料健康檢查畫面:摘要 pill(正常/無資料/未實作計數 + 最後檢查時間)+ 15 筆 Model 列表(狀態圖示、今日/本月/總計、最後記錄、未實作紅字)+ 狀態說明圖例,AppBar 有重新整理按鈕。
Swift:4 sections: (1) Header — ticket.fill icon (40pt orange), title '自動派券到會員的 Wallet', subtitle text. (2) Existing Coupons — Label with list icon; loading/empty/list states; each coupon card has title, code badge, active status pill (green/secondary), discount row (percent or amount label + icon in orang
'新增等級' / '新增獎勵' action rows use Icons.add_circle_outline (outline) while Swift uses plus.circle (filled). Semantics identical; fill style differs slightly.
餐廳位置 mini-map:Swift renders a real MapKit LoyaltyMapSnippet with map tiles (height 150); Flutter uses a tinted background container + Icons.location_on placeholder — acceptable for a static gallery render but lacks real map texture.
🟢 對齊電子菜單上傳
settings-menu-pdf
Swift:電子菜單 PDF 上傳管理 Sheet,含「目前狀態」(已上傳/尚未上傳兩種態)、「操作」(上傳/更換/刪除+10MB footer)、條件性錯誤訊息區塊、「說明」三條 Label,NavigationBar 標題「電子菜單」+右側「完成」按鈕。
Swift:四個互斥全螢幕狀態:QR 掃描器(相機預覽鋪滿+250×250 白框+橘色 L 角+提示文字+底部手動輸入膠囊)、手動輸入(keyboard 圖示+6位等寬 TextField+開始配對橘按鈕+返回掃描次要按鈕)、相機權限被拒(camera.fill+前往設定+手動輸入)、配對結果(成功綠勾/失敗紅三角+重新掃描/完成/關閉按鈕)。導航列「配對 Apple Watch」+「關閉」左鈕。
Swift:NavigationStack + Form. Toolbar: 取消 (cancel) leading, 儲存 (semibold) trailing. Confirm alert on save. Sections: (1) 方案資訊 — 3 read-only LabeledContent rows (方案代碼, Tier, 顯示名稱). (2) 價格(NT$)— single TextField. (3) 規模限額 — 3 HStack rows with 80pt-wide left label (員工上限/分店上限/每月訂位) + TextField. (4) 進階旗標 — 3 T
缺口 1 項
Warning footer section: Flutter renders it via _section(header:null) which still wraps content in a surfaceLight rounded-card Container, giving it the same card appearance as other sections. Swift Section { warningFooter } without a header renders as a borderless, background-less grouped-list footer. The screenshot confirms the footer text appears inside a card in Flutter rather than as bare footer text.
🟡 小差訂閱方案切換器
settings-subscription-tester
Swift:NavigationStack (inline title '🧪 訂閱方案切換器' + '完成' trailing button). Three List sections: (1) '目前訂閱' — currentRow: displayName headline + statusBadge (green/red pill), HStack with person.2/building.2/dollarsign.circle-or-gift labels, '有效至:' caption2 date. (2) '快速動作' (conditional on currentSub != nil)
缺口 1 項
Trailing arrow icon in plan rows: Swift uses 'arrow.right.circle' (outlined circle with arrow), Flutter uses Icons.arrow_circle_right which renders as a filled dark-blue solid circle. Render confirms filled vs outline visual difference.
🟢 對齊功能開關(Debug)
settings-debug-flags
Swift:功能開關列表頁:頁首 summary card(啟用數 + Wave on/total 統計格)、說明區(兩段說明文字 + 紅色重置全部按鈕)、依 Wave 分組的 flag 行(risk/status/graduated badge、路徑 dot 指示、rawValue monospace、Toggle 或已畢業 seal 圖示)。
Swift:NavBar: center=customerName(headline)+phone(caption/textSub), right=ellipsis.circle menu (close/reopen/call). MessageList: LazyVStack on StitchColors.background. Bubbles: system=centered capsule (secondaryAdaptive bg, caption1, textSub); customer=gray-left (secondary bg, senderName caption2 above, t
缺口 1 項
More-menu icon: Swift uses SF Symbol 'ellipsis.circle' (three dots inside a circle outline). Flutter uses Icons.more_horiz (plain three horizontal dots, no enclosing circle). The circle outline is visually absent in the render.
Swift:UIKit DualPanelHostController: two UIHostingController panels side-by-side separated by a 6pt DividerView (pan to resize 25–75%, double-tap resets to 50/50, spring anim on release, blue preview line while dragging). Each panel = DualPanelContent: tab bar (HStack spacing:2, bg Color(white:0.96)=#F5F5
缺口 1 項
Left-panel tab bar overflows by 11 px at the default 50/50 ratio — Flutter overflow yellow stripe clearly visible in the screenshot ('RIGHT OVERFLOWED BY 11 PIXELS'). The three Expanded tab chips collectively exceed the panel's pixel width on this device frame. Swift uses natural-width tabs + trailing Spacer (no overflow). Fix: reduce minimum padding or font size inside _tabChip, or switch to non-Expanded flexible sizing with a trailing Spacer to mirror Swift's HStack + Spacer() behaviour.