test/framework/business/meal_reminder.py
2026-03-17 14:59:41 +08:00

96 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
from datetime import datetime
from framework.core.base_api import BaseAPI
from framework.config.settings import Config
from framework.core.logger import get_logger
logger = get_logger("MealReminderService")
class MealReminderService(BaseAPI):
MEAL_PERIODS = {
"breakfast": {
"range": (6, 9), "emoji": "🌅", "label": "早餐", "keywords": "早餐|早点|咖啡",
"greetings": ["早安!中关村的早晨从热腾腾的早点开始 ☀️", "美好的早晨,看看附近有什么好吃的早餐 ☕"]
},
"lunch": {
"range": (10, 13), "emoji": "☀️", "label": "午餐", "keywords": "餐厅|快餐|中餐",
"greetings": ["午饭时间到!放下代码,看看公司附近吃什么 🍚", "到点干饭了,为您搜罗了附近的优质午餐 🤔"]
},
"afternoon_tea": {
"range": (14, 16), "emoji": "🍰", "label": "下午茶", "keywords": "甜品|饮品|咖啡",
"greetings": ["下午茶时间~来点甜的补充能量 🧁", "三点几嚟,饮茶先啦!🫖"]
},
"dinner": {
"range": (17, 20), "emoji": "🌆", "label": "晚餐", "keywords": "特色菜|火锅|烧烤|餐厅",
"greetings": ["下班啦!中关村的夜晚,吃顿好的犒劳自己 🎉", "晚餐时间到,看看壹号周边有哪些人气餐厅 🍽️"]
},
"late_night": {
"range": (21, 5), "emoji": "🌙", "label": "夜宵", "keywords": "烧烤|宵夜|快餐",
"greetings": ["深夜食堂正式营业!🏮", "加班辛苦了,看看附近有什么深夜美食 🌙"]
},
}
def __init__(self):
super().__init__("https://restapi.amap.com") # 高德 API 基地址
def get_current_period(self) -> dict:
hour = datetime.now().hour
for period_info in self.MEAL_PERIODS.values():
start, end = period_info["range"]
if start <= end:
if start <= hour <= end: return period_info
else:
if hour >= start or hour <= end: return period_info
return self.MEAL_PERIODS["lunch"]
def fetch_nearby_restaurants(self, keywords: str) -> list:
endpoint = "/v3/place/around"
params = {
"key": Config.AMAP_KEY,
"location": Config.AMAP_COORDINATES,
"keywords": keywords,
"types": "050000", # 餐饮服务
"radius": 1000,
"sortrule": "weight",
"offset": 10,
"page": 1,
"extensions": "all"
}
try:
# BaseAPI.request 默认会拼 BASE_URL这里高德是不同的地址手动处理或实例化时指定
import requests # 临时直接用 requests或者修改 BaseAPI 支持绝对路径
resp = requests.get(f"{self.base_url}{endpoint}", params=params, timeout=5)
data = resp.json()
if data.get("status") == "1":
return data.get("pois", [])
except Exception as e:
logger.error(f"高德 API 调用失败: {e}")
return []
def build_card(self) -> dict:
period = self.get_current_period()
greeting = random.choice(period["greetings"])
pois = self.fetch_nearby_restaurants(period["keywords"])
elements = [{"tag": "div", "text": {"tag": "lark_md", "content": f"**{greeting}**"}}, {"tag": "hr"}]
if pois:
for poi in pois[:5]:
name = poi.get("name", "未知餐厅")
biz_ext = poi.get("biz_ext", {})
rating = biz_ext.get("rating") if isinstance(biz_ext, dict) else "暂无"
distance = poi.get("distance", "未知")
elements.append({
"tag": "div",
"text": {"tag": "lark_md", "content": f"🏠 **{name}**\n⭐️ 评分: {rating} | 📍 距离: {distance}m"}
})
else:
elements.append({"tag": "div", "text": {"tag": "lark_md", "content": "⚠️ 暂时没搜到附近的店"}})
elements.extend([{"tag": "hr"}, {"tag": "note", "elements": [{"tag": "plain_text", "content": f"🕒 {datetime.now().strftime('%H:%M')}"}]}])
return {
"header": {"title": {"tag": "plain_text", "content": f"{period['emoji']} 饭否 · {period['label']}实时推荐"}, "template": "orange"},
"elements": elements
}