10 / WORK / CASE STUDY
業務外勤現場開通 PWA
給美業 B2B 通路業務員在客戶現場使用的手機優先 PWA:拍名片、當場開通企業客戶帳號、管理 CRM 與追蹤獎金;六天從零建置,已部署。
- TYPE
- FRONTEND
- SCOPE
- 公司內部 · 已部署
- STACK
- REACT · VITE · MUI · REACT-QUERY · ZUSTAND · PWA
- LINKS
- 公司內部專案(不公開)
01 / PROBLEM
B2B 通路的業務員過去要幫客戶開通企業帳號,得先抄下資料、回辦公室用另一套後台操作,客戶當下無法直接下單;業務自己的獎金、待審核客戶與 CRM 進度也分散在不同系統。這個 PWA 把「現場拍名片 → 當場建立並開通帳號 → 客戶立即可下單」收斂成一支手機瀏覽器就能完成、可安裝離線使用的流程,並把獎金查詢、CRM 與客戶審核整合進同一個前台;服務對象是美業 B2B 通路的外勤業務。
02 / CONSTRAINTS
- 公司內部專案,程式碼不公開;已部署於內部網域。
- 外勤現場網路品質不受控:任何操作——尤其開戶送出——都必須在斷網或逾時時有本機暫存與自動重送,不能讓業務白填一次表單。
- 名片影像屬客戶個資:OCR 完全在裝置端執行,不把影像外送任何第三方服務——這也是無雲端 OCR 預算下的自建解。
- 前端純消費後端 API,不落地任何業務規則:獎金計算與權限判定皆由後端決定。
03 / ARCHITECTURE
React 18 + Vite 6 SPA:MUI 5 元件、TanStack React Query 5 管伺服端快取、Zustand 只放一份登入身分狀態——17 個路由畫面、6 個 API 模組共 50 個呼叫點,對接平台的 4 個後端服務(認證、獎金、CRM、店家),全站約 8,200 行。刻意維持極簡狀態設計:伺服端資料一律進 React Query,客戶端狀態只有登入身分一項。
橫切設計:Axios 攔截器統一附加 token 與 401 刷新(併發請求排隊、只刷新一次);Service Worker 只做 app shell 離線容忍(靜態資源 cache-first、API 一律不快取);現場開戶頁自建三層弱網韌性——草稿即時落地、送出失敗轉本機離線佇列、連線恢復自動重送;OCR 以 tesseract.js 全跑瀏覽器端。部署為 nginx 靜態站,API 走同網域反向代理。
04 / RESPONSIBILITIES
獨立開發:從空 repo 到部署共 6 天(2026/07/10–07/15),全部 commit 出自我一人;需求整理、架構、實作與部署皆由我完成。後端 API 為平台既有服務,不在本專案範圍。
05 / CHALLENGES → SOLUTIONS
CHALLENGE
店家頁一開始直打既有後端給其他前台用的查詢端點:拿不到業務員對應的內部歸戶 ID 時,它不報錯,而是靜默改用 user_id 過濾——畫面完全正常,但業務看到的店家清單是錯的。
SOLUTION
改走後端提供的業務專屬端點,由後端解析登入業務的歸戶 ID 再過濾,前端不再自組歸戶邏輯;同一次提交把登入換成業務專屬閘門(消費者帳號一律 403)。修正只有 2 個檔案 14 行,解決的卻是「看起來正常、資料是錯的」這類最難被發現的 bug。
CHALLENGE
訂單退貨後,後端會回沖對應獎金,但三個獎金畫面仍顯示原始金額——業務看到的數字,和公司實際會發放的淨額對不起來。
SOLUTION
三頁一次改成淨額口徑(獎金-回沖):有回沖的紀錄標示回沖金額、全額回沖用刪除線保留原額,讓業務看得懂「這筆錢去哪了」,而不是數字憑空消失。
CHALLENGE
現場開戶是核心流程,但網路品質是客戶店裡有什麼就是什麼;名片又是客戶個資,不能送第三方雲端 OCR,公司也沒有採購預算。
SOLUTION
弱網做三層:表單變動即存本機草稿、送出遇連線失敗轉離線佇列、瀏覽器恢復連線自動重送。OCR 以 tesseract.js 在裝置端跑,只預填仍為空的欄位、不覆蓋手動輸入,結果一律由業務核對後才送出——零後端支援、零額外預算的純前端解。
06 / SYSTEM FACTS
17
路由畫面
50
API 呼叫點
~190KB
vendor bundle(gzip)
6
天,從零到部署
07 / LESSONS
「查得到資料」不等於「資料是對的」——靜默降級比顯式錯誤更危險。共用端點在邊界情況下換了一套過濾邏輯而不報錯,呼叫端幾乎無從分辨。之後接既有端點,會先確認它的降級行為,而不是看到 200 就當作正確。
弱網韌性要在設計期決定,事後補難得多:草稿、佇列、自動重送要嵌回已完成的表單狀態機,遠比一開始一起做困難。誠實的現狀是這個專案沒有自動化測試(斷網情境靠手動驗證),若要繼續維護,第一件事是替離線佇列與重送補上測試。
NEXT
股東常會電子投票系統