diff --git a/app/Linebot_handler/Expense.py b/app/Linebot_handler/Expense.py index f89c84c..237fc5b 100755 --- a/app/Linebot_handler/Expense.py +++ b/app/Linebot_handler/Expense.py @@ -239,21 +239,38 @@ def query_month(line_user_id: str) -> str: try: user_id = get_or_create_user(db, line_user_id) now = datetime.now() - rows = db.query(Expense).filter( - Expense.user_id == user_id, - text("EXTRACT(YEAR FROM date) = :year AND EXTRACT(MONTH FROM date) = :month") - ).params(year=now.year, month=now.month).all() + + sql = text(""" + SELECT + COALESCE(m.display_name, e.item_name) AS display_name, + SUM(e.amount) as total_amount + FROM expenses e + LEFT JOIN merchant_mapping m ON e.seller_name LIKE '%' || m.pattern || '%' + WHERE e.user_id = :user_id + AND EXTRACT(YEAR FROM e.date) = :year + AND EXTRACT(MONTH FROM e.date) = :month + GROUP BY display_name + ORDER BY total_amount DESC + """) + + rows = db.execute(sql, {"user_id": user_id, "year": now.year, "month": now.month}).fetchall() if not rows: return "本月還沒有記錄 📭" total = sum(float(r.amount) for r in rows) summary = {} - for r in rows: - key = r.item_name or "其他" - summary[key] = summary.get(key, 0) + float(r.amount) - lines = [f"{cat}:${amt:.0f}" for cat, amt in sorted(summary.items(), key=lambda x: -x[1])] - return f"📊 本月統計({now.month}月):\n" + "\n".join(lines) + f"\n\n💰 總計:${total:.0f}" + for row in rows: + name = row.display_name + amt = float(row.total_amount) + percent = (amt / total) * 100 + # 加上一點視覺效果 + summary.append(f"🔹 {name}:${amt:.0f} ({percent:.1f}%)") + + header = f"📊 {now.year}年{now.month}月 消費統計" + divider = "--------------------------" + footer = f"\n{divider}\n💰 本月總支出:${total:.0f}" + return f"{header}\n{divider}\n" + "\n".join(summary) + footer except Exception as e: print("❌ 查詢失敗:", e) return "查詢失敗,請稍後再試"