模組總覽
美業預約做什麼
完整的美髮 / 美甲 / SPA 等需要設計師排班 + 服務組合 + 結帳收銀的店家流程:
- 服務人員 / 職稱:依設計師等級加價(資深 / 名師 / 總監)
- 服務項目:含時長、價格、可選副選項(如染髮加深染、護髮升級)
- 班表:每位設計師每日早 / 晚班 + 例假;支援 Excel 匯入
- 預約看板 / 日曆:查預約 / 改狀態 / 手動建預約
- POS 開單收銀(Phase 3):店員現場開單結帳,獨立於預約
- 訂單查詢(Phase 4):依日期 / 設計師 / 狀態查找
- 業績結算(Phase 4):按日 / 按設計師 / 按分店三維度
- 儲值金(會員確認制):扣款前先推 LINE 給會員確認
- 派工單:服務後自動建單給設計師填寫服務細節
- 行銷活動:閃購 / 滿額折扣 / 滿額贈品
POS 端 sidebar 7 項
| 路徑 | sidebar 標籤 | 對象 |
|---|---|---|
| /pos/beauty/reservations | 看板 | 店員、櫃台 |
| /pos/beauty/timetable | 班表(時間軸) | 店員、店長 |
| /pos/beauty/calendar | 日曆 | 老闆、櫃台 |
| /pos/beauty/checkout | 開單 | 店員、櫃台 |
| /pos/beauty/orders | 訂單 | 店員、店長 |
| /pos/beauty/settlement | 結算 | 店長、老闆 |
| /pos/beauty/balance | 儲值扣款 | 店員 |
F112 不同分類並排開關 / F113 多項合併顯示(詳見「預約參數」)
- F112 不同分類並排(parallel_cross_category):開啟後,顧客一次預約不同分類的多項服務時,系統可安排同時段由不同設計師同時施作,縮短整體等待時間。詳細設定方式見
預約參數 → 不同分類項目並排。 - F113 多項預約合併一張卡(booking_group_id):同次預約的多張單共享同一個
booking_group_id,LIFF「我的預約」頁面自動合併成一張卡顯示,方便顧客確認整組服務內容。
多項預約自動分單(2026-06-18 新行為)
顧客在 LIFF 一次預約 2 項以上服務 → 後端自動拆成 N 張獨立預約單:
- 每張單獨立的
reservation_no(連號 e.g. R20260618-0007 + R20260618-0008) - 每張各自 1 個 staff_id / service / duration / price
- 時間 sequential 累加:item 1 在 14:00、item 2 從 14:00+item1_duration 開始
- 後台看板看到 N 張獨立卡片,可分別:拖拉改時段、換設計師、取消、開單結帳
- LINE 推播 + LIFF 我的預約頁同樣每張獨立顯示
單項預約仍是 1 張單,行為完全不變。舊資料(1 張單 + 多項 items[])仍能正常顯示。
班表(時間軸)— 拖拉操作(2026-06-17 升級 / 2026-07-20 新增長按防誤觸 + 橫向鎖)
/pos/beauty/timetable 是直觀的時間軸視圖:橫向欄=該日上班設計師、左軸=時間(一格幾分鐘依「預約參數 → 預約時段間隔」,預設 15 分、每小時粗線)、預約以彩色 block 顯示在對應欄。
格線和顧客看到的時間選項是同一個設定
- 顏色區分上班/非上班:每位設計師欄內,上班時段淡綠底(emerald-500/5)、非上班時段暗灰底(一眼看出可受預約區間)
- 休假員不顯示:當日
is_off=true或沒排班的設計師完全不出現在欄位(避免誤排);綁到休假員的舊預約自動歸到「未指定」欄 - 長按才能拖(2026-07-20 新增,防平板誤觸):要拖動一張預約,得先按住約 0.25 秒才會進入拖曳模式;輕點一下是開啟預約詳情、手指滑動則是捲動頁面,都不會誤拖。平板上翻頁再也不會不小心把客人的時間拖歪。
- 拖 block 主體 → 改時段(每次移動一格,一格幾分鐘依「預約時段間隔」,預設 15 分)+ 拖到不同欄 = 換設計師。拖的是「移動幾格」而非「對齊到格線」:09:15 的預約往下拖一格(間隔 30 分)會變 09:45,仍保留客人原本約好的分鐘數;要改成整點請點進預約卡直接輸入時間
- 拖 block 底部 8px handle → 改 duration(最短 1 格、最長 720 分)
- 可鎖成「只能左右換設計師」:若在「預約參數」開了「班表拖曳只限橫向」開關,拖曳時上下(時間軸)會被鎖住、只能左右換設計師欄,避免不小心改到時間;要改時間就點進預約卡修改。預設關閉(可自由拖曳)。詳見「預約參數 → 班表拖曳只限橫向」。
- 拖曳中顯示橙色虛線 ghost + 目標時間 / 設計師名稱
- 衝突(不在班 / 時段被預約 / 全店滿)→ 自動 409 擋下 + toast 提示 + 還原視覺
- 多項預約(指定不同設計師)會自動拆成 N 個 block 分落各設計師欄,依 sort_order 累加時間,標
1/2、2/2徽章;拆出來的 item block 不開放拖(避免語意混淆) - 班表右上角「+ 手動預約」按鈕(2026-06-19):跟看板用同一個手動預約 modal,店員臨櫃接電話直接從班表頁開單;多店租戶 modal 內只列當前門市的設計師(自動 filter)。手動預約電話為非必填(散客留 walk-in 名字也能建)。
鈴鐺 / 看板 / 日曆 / 訂單看到的客戶名後面會自動顯示會員標籤 chip(VIP、首購等顏色框),員工辨識重點客戶更快;LINE 推播給設計師的文案也帶 [VIP][首購]。「指定」標籤 — 一眼看出客人指定了設計師(2026-07-20 新增)
當顧客在 LINE 前台(LIFF)預約時自己點選了要哪一位設計師,這張預約在後台會特別標示:
- 紅色外框 + 紅底「指定」標籤,出現在看板 / 班表(時間軸)/ 日曆 / 清單 / 預約詳情每一個看得到這張預約的地方。班表時間軸的卡片上,「指定」標籤在卡片右下角。
- 顧客沒有指定(由系統或店家分配設計師)、或是舊資料,就不會有紅框與標籤,維持一般樣式。
用途:店員排班、調人時一眼看出「這位客人是指定某設計師來的」,避免不小心把指定客調給別人做,引起客訴。
提示:員工只看得到自己店的資料;老闆可在 sidebar 頂部「當前門市」切換看 / 操作各店。
多分店設定
本租戶若已開多家分店,本模組設定屬「per-store」(每間分店各自獨立設定)。 畫面頂部會看到 banner:
- 橘色「正在編輯:[分店名]」→ 編輯的是該分店私有設定
- 黃色「正在編輯:全店共用設定」→ 影響所有分店
切換分店:左上角當前門市切換器。
單店租戶看不到 banner(系統自動隱藏)。
per-store 涵蓋範圍(美業預約)
可分店各自一份的設定 key(存在 beauty_settings,namespace key@storeId):
| key | 對應功能 |
|---|---|
shifts | 班別設定(早班 / 晚班…) |
exception_shifts | 特殊日期 / 店休 |
reservation_config | 預約功能設定(提前天數 / pending 自動取消…) |
business_day_boundary_hour | 業務日切換時間(跨夜店) |
work_order_config | 派工單規則(鎖定天數 / 完成推 LINE) |
可分店各自一份的 per-store 資料表:
beauty_staff_titles(職稱 / 指定設計師加價) —store_id IS NULL代表全店共用beauty_work_order_templates(派工單範本) —store_id IS NULL代表全店共用
分店設定改成逐欄沿用(2026-08-17):分店明確設過的欄位照舊蓋過全店,分店那份沒有的欄位才沿用全店。舊行為是整包二選一 —— 分店只要存過一次,之後全店新增的欄位對該分店永遠不生效(「預約時段間隔」剛上線時就是踩到這條)。設定頁每張卡上方會顯示範圍標籤,告訴您這張卡是本店專屬、沿用全店、還是部分沿用,詳見「預約參數」。
只有一家分店的店家(2026-08-17 修正):顧客端沒帶分店時,系統會自動套用該租戶唯一那家分店的設定 —— 先前這種租戶在後台設的預約參數顧客端讀不到,一律看到系統預設值。兩家以上分店維持原行為(讀全店共用設定,不替顧客挑店)。
預約狀態流(看板 / 日曆 / 班表 共用 detail modal)
看板、日曆、班表三個頁面點任一預約 block 彈出的詳情 modal 完全一致,狀態轉換按鈕依當前狀態動態切換。
pending(待確認)
│
├─→ ✓ 確認預約 → confirmed
└─→ ✓ 確認並派工設計師 → → confirmed(同時派工)
※ 預約若沒指定設計師,按確認時系統會跳出派工選擇器,
只列「同店 + 該時段有班 + 沒衝突」的設計師
│
confirmed / waiting(等待中)
│
└─→ 客人已到(進行中) → seated
│
seated(進行中)
│
├─→ 開單 →(跳 POS 選項目) → POS 自動帶會員 / 設計師
│ 建單後預約進「未付款」欄
│ └─→ 結帳 → → /pos/beauty/checkout-pending
│
└─→ ✓ 直接完成(不開單) → completed(緊急用,不留訂單)改時間 / 改時長
confirmed / waiting / seated 三種狀態都可改開始時間 + 時長;後端會驗證該設計師的班表與是否與其他預約衝突,衝突會擋下。
開始時間用「時 / 分」兩個 24 小時制下拉選(2026-08-17 起,分鐘 5 分一格)。手動預約 modal 的「時間」欄位也是同一套。改動原因與班表頁相同:原本的時間欄位顯示上午 / 下午由裝置語言決定,17:20 這種晚班時段容易看錯設錯;改成下拉後每台平板看到的都一致。舊資料若是 09:17 這種非 5 分格線的時間,會被完整保留、不會被吸到最近的格點。
看板鈴鐺
看板右上鈴鐺撈「最近 24 小時建立的所有預約」(跨日期),所以明天的預約建立時也會立刻響,不必等到當天才知道有新單。
不顯示在班表 / 日曆的單
cancelled(取消)與 no_show(未到)的預約不再出現在班表 / 日曆,只在「訂單管理 / 預約列表」可查到。
公開預約 API 的時段擋法
- 當日預約:已過時間的時段不開放(避免會員點到過去時間)
- 不指定設計師:當該時段「同店所有設計師都已被排滿」時,公開 API 也擋下不可選
名額怎麼算(2026-09-03 起線上預約「指定」與「不指定」同一個公式)
- 每個時段的剩餘名額 = 在班且能做該項目的設計師人數 − 已被指定預約佔走的人數 − 與該時段重疊的「不指定」預約張數,大於 0 才開放。
- 「不指定」預約不歸戶到某一位設計師,而是從全店名額扣一個位子;因此指定某位設計師時,即使他本人有空,若名額已被不指定預約占滿,也會被擋下(文案:「本人有空,但該時段名額已被不指定預約占滿」),這樣才留得住人給不指定的客人。
- 前台反灰的時段與送出時後端擋下的時段用同一個公式;「不同分類並排」開啟時,並排組內每一項也各自套用(同組已分配的設計師不重複計入)。
- 同一家店同一天的建單(線上與後台)會排隊序列化,兩位客人同時搶最後一個名額只會成功一位,另一位收到「請選其他時間」;等待超過 8 秒會回「同時段預約人數較多,請稍後再試一次」。
- 後台手動建單預設不受上述檢查限制(只提示),可在「預約參數 → 後台建單可超過名額/班表」關閉,關閉後店員也會被擋。
會員資料與預約姓名
「預約姓名」預設空白(2026-06-16 起)
情境:顧客加 LINE 官方帳號為好友時,系統會自動把 LINE 顯示名稱(含 emoji 暱稱)寫入會員的「姓名」欄位,方便店家辨識。
問題:直接拿 LINE 暱稱當作真實姓名會發生:
- 預約時自動填「柯佳佳」這種暱稱(不適合當作預約姓名)
- 店家在客戶資料上看不出哪些是會員自己填的真名
新規則:
- 顧客進 LIFF 預約 / 會員資料頁時,若 members.name 等於 LINE 顯示名稱 → 姓名欄位預設留空,等顧客自填真名
- 顧客一旦填過真名(≠ LINE 顯示名稱),下次預約自動帶上
- 後台改過會員姓名 → 下次預約帶新值
- 顧客若把預約姓名故意填得跟 LINE 一樣 → 不寫入(防呆,避免再進 fallback 狀態)
散客自動合併(2026-06-16 起)
情境:店員手動建散客(沒 LINE)→ 顧客之後加 LINE OA → 顧客 LIFF 預約填手機。
舊行為:散客跟 LINE 會員是兩筆,需要店家手動跑「合併重複會員」才能整併。
新行為:LIFF 預約時帶 phone + line_user_id,後端自動把同 phone 的散客(沒 line_id 那筆)合併到 LINE 會員 — 散客所有預約 / 訂單 / 標籤 / 票券 / 集點等 28 個關聯表自動接過來,散客 row 刪除。店家無需動手。
LIFF 會員資料頁(/m/profile)也有同樣自動合併(更早就有)。