File size: 5,108 Bytes
91b069f
4bfed4c
dbf3645
 
 
 
 
 
 
 
 
 
 
 
 
 
6320354
dbf3645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bfed4c
dbf3645
6320354
dbf3645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ccfb5f6
dbf3645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91b069f
ccfb5f6
dbf3645
ccfb5f6
dbf3645
 
 
 
 
 
e20d451
dbf3645
ccfb5f6
e20d451
91b069f
 
dbf3645
 
 
 
 
 
e20d451
dbf3645
7bb2e5d
 
dbf3645
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import gradio as gr
from datetime import datetime, timedelta
import os
import requests
from supabase import create_client, Client

# --- 連線設定 ---
LINE_ACCESS_TOKEN = os.getenv("LINE_ACCESS_TOKEN")
LINE_ADMIN_ID = os.getenv("LINE_ADMIN_ID")
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)

# --- LINE 通知函式 (更新版:包含備註) ---
def send_line_notify(data):
    if not LINE_ACCESS_TOKEN or not LINE_ADMIN_ID: return
    
    msg_body = [
        {"type": "text", "text": "姓名", "color": "#aaaaaa", "size": "sm", "flex": 2},
        {"type": "text", "text": data['name'], "wrap": True, "color": "#666666", "size": "sm", "flex": 5},
        {"type": "text", "text": "電話", "color": "#aaaaaa", "size": "sm", "flex": 2},
        {"type": "text", "text": data['tel'], "wrap": True, "color": "#666666", "size": "sm", "flex": 5},
        {"type": "text", "text": "Email", "color": "#aaaaaa", "size": "sm", "flex": 2},
        {"type": "text", "text": data.get('email', '-'), "wrap": True, "color": "#666666", "size": "sm", "flex": 5},
        {"type": "text", "text": "備註", "color": "#aaaaaa", "size": "sm", "flex": 2},
        {"type": "text", "text": data.get('remarks', '無'), "wrap": True, "color": "#666666", "size": "sm", "flex": 5}
    ]
    
    # ... (此處省略部分重複的 Flex Message 結構,重點是把上面的 msg_body 塞進去) ...
    # 為了節省篇幅,這裡直接發送簡單通知,您可以用之前的 Flex Message 結構替換
    requests.post(
        "https://api.line.me/v2/bot/message/push",
        headers={"Authorization": f"Bearer {LINE_ACCESS_TOKEN}", "Content-Type": "application/json"},
        json={"to": LINE_ADMIN_ID, "messages": [{"type": "text", "text": f"🔥 新訂位:{data['name']} ({data['pax']}人)\n時間:{data['date']} {data['time']}\n備註:{data.get('remarks', '無')}"}]}
    )

# --- 核心邏輯 ---
def handle_booking(name, tel, email, date_str, time, pax, remarks):
    if not name or not tel or not date_str or not time:
        return "⚠️ 請完整填寫必填欄位"
    
    data = {
        "name": name, "tel": tel, "email": email, 
        "date": date_str, "time": time, "pax": pax, 
        "remarks": remarks, "status": "待處理"
    }
    
    try:
        # 寫入資料庫
        supabase.table("bookings").insert(data).execute()
        # 發送 LINE
        send_line_notify(data)
        return """<div style='text-align: center; color: #fff; padding: 20px; border: 1px solid #d4af37; border-radius: 8px; background: #222;'>
            <h2 style='color: #d4af37;'>Request Received</h2><p>🥂 預約申請已提交,請留意確認信。</p></div>"""
    except Exception as e:
        return f"❌ 系統錯誤: {str(e)}"

# --- 處理確認連結 (Webhook) ---
def check_confirmation(request: gr.Request):
    """
    當網址帶有 ?id=xx&action=confirm 時觸發
    """
    if not request: return ""
    params = request.query_params
    action = params.get('action')
    bid = params.get('id')
    
    if action == 'confirm' and bid:
        try:
            # 更新資料庫狀態
            supabase.table("bookings").update({"status": "顧客已確認"}).eq("id", bid).execute()
            return f"""
            <script>
                document.addEventListener('DOMContentLoaded', function() {{
                    alert('✅ 感謝您!訂位已確認 (編號 {bid})');
                }});
            </script>
            <div style='padding:20px; background:#d4af37; color:black; text-align:center; margin-bottom:20px; border-radius:8px;'>
                🎉 感謝您的確認!我們期待您的光臨。
            </div>
            """
        except:
            return ""
    return ""

# --- 介面佈局 ---
# 主題與 CSS 設定 (沿用之前的) ... 

with gr.Blocks(theme=gr.themes.Soft(), title="Booking") as demo:
    # 隱藏的 HTML 區塊,用來接收確認訊息
    confirm_msg_box = gr.HTML()
    
    # 頁面載入時檢查網址參數
    demo.load(check_confirmation, inputs=None, outputs=confirm_msg_box)

    # ... (Header 與 日期選擇區塊 保持不變) ...

    gr.Markdown("### 👤 聯絡人資料 Contact")
    with gr.Group():
        with gr.Row():
            cust_name = gr.Textbox(label="訂位姓名 *", placeholder="ex. 王小明")
            cust_tel = gr.Textbox(label="手機號碼 *", placeholder="ex. 0912-xxx-xxx")
        with gr.Row():
            cust_email = gr.Textbox(label="電子信箱 (接收確認信用)", placeholder="example@gmail.com")
        with gr.Row():
            cust_remarks = gr.Textbox(label="備註 (過敏/慶生/特殊需求)", lines=2)

    submit_btn = gr.Button("確認預約 Request Booking", variant="primary")
    output_msg = gr.HTML()
    
    # ... (Event Listeners) ...
    submit_btn.click(
        handle_booking, 
        inputs=[cust_name, cust_tel, cust_email, booking_date, time_slot, pax_count, cust_remarks], 
        outputs=output_msg
    )

demo.launch()