DeepLearning101 commited on
Commit
5dfbc08
·
verified ·
1 Parent(s): 053a647

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -8
app.py CHANGED
@@ -85,13 +85,13 @@ def get_line_id_from_url(request: gr.Request):
85
  def handle_booking(name, tel, email, date_str, time, pax, remarks, line_id):
86
  # 1. 基本必填檢查
87
  if not name or not tel or not date_str or not time:
88
- return "⚠️ 請完整填寫必填欄位 (姓名、電話、日期、時間)"
89
 
90
  # 🔥🔥🔥 [新增] 格式驗證邏輯 🔥🔥🔥
91
 
92
  # 2. Email 驗證 (如果用戶有填寫 Email,就必須包含 @)
93
  if email and "@" not in email:
94
- return "⚠️ Email 格式錯誤 (請確認包含 @ 符號)"
95
 
96
  # 3. 電話驗證 (寬鬆模式:相容外國人)
97
  # 邏輯:不限制符號 (+, -, 空白, 括號都可),但「數字」的總數至少要有 6 碼
@@ -99,7 +99,7 @@ def handle_booking(name, tel, email, date_str, time, pax, remarks, line_id):
99
  # 例如: "Test Phone" (數字0碼) -> 失敗
100
  digit_count = sum(c.isdigit() for c in tel)
101
  if digit_count < 6:
102
- return "⚠️ 電話號碼格式錯誤 (請填寫有效的電話號碼)"
103
 
104
  # 🔥🔥🔥 驗證結束 🔥🔥🔥
105
 
@@ -109,12 +109,12 @@ def handle_booking(name, tel, email, date_str, time, pax, remarks, line_id):
109
  res = supabase.table("bookings").select("pax").eq("date", date_str).neq("status", "顧客已取消").execute()
110
  current_total = sum([item['pax'] for item in res.data])
111
  if current_total + pax > daily_limit:
112
- return "⚠️ 抱歉,該時段剩餘座位不足,請調整人數或日期。"
113
  except: pass
114
 
115
  try:
116
  existing = supabase.table("bookings").select("id").eq("tel", tel).eq("date", date_str).eq("time", time).neq("status", "顧客已取消").execute()
117
- if existing.data: return "⚠️ 您已預約過此時段,請勿重複提交。"
118
  except: pass
119
 
120
  data = {
@@ -141,8 +141,14 @@ def handle_booking(name, tel, email, date_str, time, pax, remarks, line_id):
141
  )
142
  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": msg}]})
143
 
144
- return """<div style='text-align: center; color: #fff; padding: 20px; border: 1px solid #d4af37; border-radius: 8px; background: #222;'><h2 style='color: #d4af37; margin: 0;'>Request Received</h2><p style='margin: 10px 0;'>🥂 預約申請已提交</p><p style='font-size: 0.9em; color: #aaa;'>請留意 Email 確認信 或 Line 訊息。</p></div>"""
145
- except Exception as e: return f"❌ 系統錯誤: {str(e)}"
 
 
 
 
 
 
146
 
147
  # --- 5. Webhook (確認/取消 + 回傳轉址 URL + 🔥通知老闆) ---
148
  def check_confirmation(request: gr.Request):
@@ -210,10 +216,18 @@ custom_css = "footer {display: none !important;} .gradio-container, .block, .row
210
  with gr.Blocks(theme=theme, css=custom_css, title="Booking") as demo:
211
  line_id_box = gr.Textbox(visible=True, elem_id="hidden_box", label="LINE ID")
212
  redirect_url_box = gr.Textbox(visible=False)
 
213
 
214
  demo.load(get_line_id_from_url, None, line_id_box)
215
  demo.load(check_confirmation, None, redirect_url_box)
216
 
 
 
 
 
 
 
 
217
  redirect_url_box.change(
218
  fn=None,
219
  inputs=redirect_url_box,
@@ -250,7 +264,7 @@ with gr.Blocks(theme=theme, css=custom_css, title="Booking") as demo:
250
  gr.HTML("""<div class="legal-footer"><p style="margin-bottom: 5px;">© 2026 CIE CIE TAIPEI. All Rights Reserved.</p><p>內容涉及酒類產品訊息,請勿轉發分享給未達法定購買年齡者;未滿十八歲請勿飲酒。<br><strong>喝酒不開車,開車不喝酒。</strong></p></div>""")
251
 
252
  booking_date.change(update_time_slots, inputs=booking_date, outputs=[time_slot, status_box])
253
- submit_btn.click(handle_booking, inputs=[cust_name, cust_tel, cust_email, booking_date, time_slot, pax_count, cust_remarks, line_id_box], outputs=output_msg)
254
 
255
  if __name__ == "__main__":
256
  demo.launch()
 
85
  def handle_booking(name, tel, email, date_str, time, pax, remarks, line_id):
86
  # 1. 基本必填檢查
87
  if not name or not tel or not date_str or not time:
88
+ return "⚠️ 請完整填寫必填欄位 (姓名、電話、日期、時間)", ""
89
 
90
  # 🔥🔥🔥 [新增] 格式驗證邏輯 🔥🔥🔥
91
 
92
  # 2. Email 驗證 (如果用戶有填寫 Email,就必須包含 @)
93
  if email and "@" not in email:
94
+ return "⚠️ Email 格式錯誤 (請確認包含 @ 符號)", ""
95
 
96
  # 3. 電話驗證 (寬鬆模式:相容外國人)
97
  # 邏輯:不限制符號 (+, -, 空白, 括號都可),但「數字」的總數至少要有 6 碼
 
99
  # 例如: "Test Phone" (數字0碼) -> 失敗
100
  digit_count = sum(c.isdigit() for c in tel)
101
  if digit_count < 6:
102
+ return "⚠️ 電話號碼格式錯誤 (請填寫有效的電話號碼)", ""
103
 
104
  # 🔥🔥🔥 驗證結束 🔥🔥🔥
105
 
 
109
  res = supabase.table("bookings").select("pax").eq("date", date_str).neq("status", "顧客已取消").execute()
110
  current_total = sum([item['pax'] for item in res.data])
111
  if current_total + pax > daily_limit:
112
+ return "⚠️ 抱歉,該時段剩餘座位不足,請調整人數或日期。", ""
113
  except: pass
114
 
115
  try:
116
  existing = supabase.table("bookings").select("id").eq("tel", tel).eq("date", date_str).eq("time", time).neq("status", "顧客已取消").execute()
117
+ if existing.data: return "⚠️ 您已預約過此時段,請勿重複提交。", ""
118
  except: pass
119
 
120
  data = {
 
141
  )
142
  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": msg}]})
143
 
144
+ html_response = """<div style='text-align: center; color: #fff; padding: 20px; border: 1px solid #d4af37; border-radius: 8px; background: #222;'><h2 style='color: #d4af37; margin: 0;'>Request Received</h2><p style='margin: 10px 0;'>🥂 預約申請已提交</p><p style='font-size: 0.9em; color: #aaa;'>請留意 Email 確認信 或 Line 訊息。</p></div>"""
145
+
146
+ # 👇 成功時,第二個參數回傳 "success"
147
+ return html_response, "success"
148
+
149
+ # return """<div style='text-align: center; color: #fff; padding: 20px; border: 1px solid #d4af37; border-radius: 8px; background: #222;'><h2 style='color: #d4af37; margin: 0;'>Request Received</h2><p style='margin: 10px 0;'>🥂 預約申請已提交</p><p style='font-size: 0.9em; color: #aaa;'>請留意 Email 確認信 或 Line 訊息。</p></div>"""
150
+
151
+ except Exception as e: return f"❌ 系統錯誤: {str(e)}", ""
152
 
153
  # --- 5. Webhook (確認/取消 + 回傳轉址 URL + 🔥通知老闆) ---
154
  def check_confirmation(request: gr.Request):
 
216
  with gr.Blocks(theme=theme, css=custom_css, title="Booking") as demo:
217
  line_id_box = gr.Textbox(visible=True, elem_id="hidden_box", label="LINE ID")
218
  redirect_url_box = gr.Textbox(visible=False)
219
+ ga4_trigger_box = gr.Textbox(visible=False)
220
 
221
  demo.load(get_line_id_from_url, None, line_id_box)
222
  demo.load(check_confirmation, None, redirect_url_box)
223
 
224
+ ga4_trigger_box.change(
225
+         fn=None,
226
+         inputs=ga4_trigger_box,
227
+         outputs=None,
228
+         js="(val) => { if(val === 'success' && window.parent) { window.parent.postMessage('booking_success', '*'); } }"
229
+ )
230
+
231
  redirect_url_box.change(
232
  fn=None,
233
  inputs=redirect_url_box,
 
264
  gr.HTML("""<div class="legal-footer"><p style="margin-bottom: 5px;">© 2026 CIE CIE TAIPEI. All Rights Reserved.</p><p>內容涉及酒類產品訊息,請勿轉發分享給未達法定購買年齡者;未滿十八歲請勿飲酒。<br><strong>喝酒不開車,開車不喝酒。</strong></p></div>""")
265
 
266
  booking_date.change(update_time_slots, inputs=booking_date, outputs=[time_slot, status_box])
267
+ submit_btn.click(handle_booking, inputs=[cust_name, cust_tel, cust_email, booking_date, time_slot, pax_count, cust_remarks, line_id_box], outputs=[output_msg, ga4_trigger_box])
268
 
269
  if __name__ == "__main__":
270
  demo.launch()