Update app.py
Browse files💣 地雷一:Pandas 遇到舊資料空值 (None) 會當機崩潰
💣 地雷二:「0 元 bug」的翻版!如果老闆手動把限量改成 0 怎麼辦?
💣 地雷三:載入編輯時,舊資料的 None 會讓畫面壞掉
app.py
CHANGED
|
@@ -315,7 +315,11 @@ def get_menu_items():
|
|
| 315 |
df['is_active'] = df['is_active'].apply(lambda x: "🟢 販售中" if x else "🔴 已下架")
|
| 316 |
df['has_image'] = df.get('image_url', pd.Series()).apply(lambda x: "🔗 有" if pd.notnull(x) and str(x).strip() else "無")
|
| 317 |
# 顯示限量 (999 顯示為無限制)
|
| 318 |
-
df['daily_limit_display'] = df.get('daily_limit', pd.Series(999)).apply(lambda x: "無限制" if x >= 999 else f"剩 {x} 份")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
|
| 320 |
display_df = df[['name', 'price', 'daily_limit_display', 'category', 'available_times', 'allow_takeout', 'require_prepay', 'is_active', 'has_image']]
|
| 321 |
display_df.columns = ['餐點名稱', '價格', '限量', '分類', '供應時段', '可外帶', '預付規則', '狀態', '照片連結']
|
|
@@ -345,19 +349,35 @@ def load_menu_data(selected_string):
|
|
| 345 |
item = res.data[0]
|
| 346 |
times = item.get("available_times", [])
|
| 347 |
if not times: times = ["晚餐 (18:30-21:30)", "宵夜 (21:30後)"] # 預設值防呆
|
| 348 |
-
|
| 349 |
return (
|
| 350 |
item.get("name", ""),
|
| 351 |
item.get("description", ""),
|
| 352 |
item.get("price", 0),
|
| 353 |
-
item.get("daily_limit", 999),
|
|
|
|
|
|
|
| 354 |
item.get("category", "main"),
|
| 355 |
times,
|
| 356 |
item.get("require_prepay", False),
|
| 357 |
item.get("allow_takeout", True),
|
| 358 |
item.get("image_url", "") or "",
|
| 359 |
-
item_id
|
| 360 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
except:
|
| 362 |
return "", "", 0, 999, "main", ["晚餐 (18:30-21:30)", "宵夜 (21:30後)"], False, True, "", ""
|
| 363 |
|
|
@@ -369,7 +389,8 @@ def add_menu_item(name, desc, price, limit, category, available_times, require_p
|
|
| 369 |
try:
|
| 370 |
data = {
|
| 371 |
"name": name, "description": desc, "price": int(price),
|
| 372 |
-
"daily_limit": int(limit) if limit else 999, # 🌟 儲存限量
|
|
|
|
| 373 |
"category": category, "available_times": available_times, "allow_takeout": allow_takeout,
|
| 374 |
"require_prepay": require_prepay, "is_active": True, "image_url": final_image_url
|
| 375 |
}
|
|
@@ -386,7 +407,8 @@ def update_menu_item(item_id, name, desc, price, limit, category, available_time
|
|
| 386 |
try:
|
| 387 |
data = {
|
| 388 |
"name": name, "description": desc, "price": int(price),
|
| 389 |
-
"daily_limit": int(limit) if limit else 999, # 🌟 儲存限量修改
|
|
|
|
| 390 |
"category": category, "available_times": available_times, "allow_takeout": allow_takeout,
|
| 391 |
"require_prepay": require_prepay, "image_url": final_image_url
|
| 392 |
}
|
|
|
|
| 315 |
df['is_active'] = df['is_active'].apply(lambda x: "🟢 販售中" if x else "🔴 已下架")
|
| 316 |
df['has_image'] = df.get('image_url', pd.Series()).apply(lambda x: "🔗 有" if pd.notnull(x) and str(x).strip() else "無")
|
| 317 |
# 顯示限量 (999 顯示為無限制)
|
| 318 |
+
# df['daily_limit_display'] = df.get('daily_limit', pd.Series(999)).apply(lambda x: "無限制" if x >= 999 else f"剩 {x} 份")
|
| 319 |
+
# 🌟 修正後的寫法 (加入 pd.isna 判斷與強制轉型):
|
| 320 |
+
df['daily_limit_display'] = df.get('daily_limit', pd.Series([999]*len(df))).apply(
|
| 321 |
+
lambda x: "無限制" if pd.isna(x) or float(x) >= 999 else f"剩 {int(float(x))} 份"
|
| 322 |
+
)
|
| 323 |
|
| 324 |
display_df = df[['name', 'price', 'daily_limit_display', 'category', 'available_times', 'allow_takeout', 'require_prepay', 'is_active', 'has_image']]
|
| 325 |
display_df.columns = ['餐點名稱', '價格', '限量', '分類', '供應時段', '可外帶', '預付規則', '狀態', '照片連結']
|
|
|
|
| 349 |
item = res.data[0]
|
| 350 |
times = item.get("available_times", [])
|
| 351 |
if not times: times = ["晚餐 (18:30-21:30)", "宵夜 (21:30後)"] # 預設值防呆
|
| 352 |
+
|
| 353 |
return (
|
| 354 |
item.get("name", ""),
|
| 355 |
item.get("description", ""),
|
| 356 |
item.get("price", 0),
|
| 357 |
+
# 原本:item.get("daily_limit", 999),
|
| 358 |
+
# 🌟 修正後:即使 get 抓到 None 也要強制轉回 999
|
| 359 |
+
item.get("daily_limit") if item.get("daily_limit") is not None else 999,
|
| 360 |
item.get("category", "main"),
|
| 361 |
times,
|
| 362 |
item.get("require_prepay", False),
|
| 363 |
item.get("allow_takeout", True),
|
| 364 |
item.get("image_url", "") or "",
|
| 365 |
+
item_id
|
| 366 |
)
|
| 367 |
+
|
| 368 |
+
# return (
|
| 369 |
+
# item.get("name", ""),
|
| 370 |
+
# item.get("description", ""),
|
| 371 |
+
# item.get("price", 0),
|
| 372 |
+
# item.get("daily_limit", 999), # 🌟 讀取限量,預設 999
|
| 373 |
+
# item.get("category", "main"),
|
| 374 |
+
# times,
|
| 375 |
+
# item.get("require_prepay", False),
|
| 376 |
+
# item.get("allow_takeout", True),
|
| 377 |
+
# item.get("image_url", "") or "",
|
| 378 |
+
# item_id # 將 ID 存入隱藏狀態中
|
| 379 |
+
# )
|
| 380 |
+
|
| 381 |
except:
|
| 382 |
return "", "", 0, 999, "main", ["晚餐 (18:30-21:30)", "宵夜 (21:30後)"], False, True, "", ""
|
| 383 |
|
|
|
|
| 389 |
try:
|
| 390 |
data = {
|
| 391 |
"name": name, "description": desc, "price": int(price),
|
| 392 |
+
# "daily_limit": int(limit) if limit else 999, # 🌟 儲存限量
|
| 393 |
+
"daily_limit": int(limit) if limit is not None else 999,
|
| 394 |
"category": category, "available_times": available_times, "allow_takeout": allow_takeout,
|
| 395 |
"require_prepay": require_prepay, "is_active": True, "image_url": final_image_url
|
| 396 |
}
|
|
|
|
| 407 |
try:
|
| 408 |
data = {
|
| 409 |
"name": name, "description": desc, "price": int(price),
|
| 410 |
+
# "daily_limit": int(limit) if limit else 999, # 🌟 儲存限量修改
|
| 411 |
+
"daily_limit": int(limit) if limit is not None else 999,
|
| 412 |
"category": category, "available_times": available_times, "allow_takeout": allow_takeout,
|
| 413 |
"require_prepay": require_prepay, "image_url": final_image_url
|
| 414 |
}
|