天气订阅功能优化

This commit is contained in:
liuwei
2025-12-17 13:23:40 +08:00
parent f4547e175e
commit 3bb5d4eef5

View File

@@ -21,25 +21,25 @@ class WeatherRedisManager:
"""处理 Redis 数据存取"""
def __init__(self, db_manager):
self.redis = db_manager
self.redis = db_manager.get_redis_connection()
self.prefix = "bot:weather:"
async def add_subscription(self, key: str, data: dict):
def add_subscription(self, key: str, data: dict):
"""添加订阅 (存入标准城市名和ID)"""
redis_key = f"{self.prefix}subs"
# 存入 JSON 字符串
await self.redis.hset(redis_key, key, json.dumps(data, ensure_ascii=False))
self.redis.hset(redis_key, key, json.dumps(data, ensure_ascii=False))
async def remove_subscription(self, key: str):
def remove_subscription(self, key: str):
"""取消订阅"""
redis_key = f"{self.prefix}subs"
await self.redis.hdel(redis_key, key)
self.redis.hdel(redis_key, key)
async def get_all_subscriptions(self) -> Dict[str, dict]:
def get_all_subscriptions(self) -> Dict[str, dict]:
"""获取所有订阅数据"""
redis_key = f"{self.prefix}subs"
try:
raw_data = await self.redis.hgetall(redis_key)
raw_data = self.redis.hgetall(redis_key)
result = {}
if raw_data:
for k, v in raw_data.items():
@@ -51,20 +51,20 @@ class WeatherRedisManager:
logger.error(f"Redis 读取订阅失败: {e}")
return {}
async def get_history(self, city_id: str) -> Optional[dict]:
def get_history(self, city_id: str) -> Optional[dict]:
"""获取某城市(ID)昨天的历史数据"""
# 注意:这里改用 city_id 作为 Key确保唯一性
redis_key = f"{self.prefix}history:{city_id}"
data = await self.redis.get(redis_key)
data = self.redis.get(redis_key)
if data:
return json.loads(data)
return None
async def save_history(self, city_id: str, data: dict):
def save_history(self, city_id: str, data: dict):
"""保存今天的核心数据 (Key 为 city_id)"""
redis_key = f"{self.prefix}history:{city_id}"
# 有效期 48 小时
await self.redis.set(redis_key, json.dumps(data, ensure_ascii=False), ex=172800)
self.redis.set(redis_key, json.dumps(data, ensure_ascii=False), ex=172800)
# ================= 插件主体类 =================
@@ -198,7 +198,7 @@ class WeatherPlugin(MessagePluginInterface):
"created_at": str(datetime.datetime.now())
}
await self.redis_manager.add_subscription(unique_id, sub_data)
self.redis_manager.add_subscription(unique_id, sub_data)
# 反馈时告诉用户标准名
msg = f"✅ 订阅成功!\n已锁定城市:{city_info['adm1']} - {std_city_name}\n每天 08:00 推送早报。"
@@ -208,7 +208,7 @@ class WeatherPlugin(MessagePluginInterface):
# 使用 ID 获取天气,避免再次 Geo 查询
weather_data = await self._fetch_weather_by_id(city_id)
if weather_data:
await self._save_today_as_history(city_id, weather_data)
self._save_today_as_history(city_id, weather_data)
return True, "订阅成功"
@@ -216,7 +216,7 @@ class WeatherPlugin(MessagePluginInterface):
elif content.startswith("取消订阅"):
if not self.redis_manager: return False, "数据库不可用"
unique_id = f"{roomid}_{sender}" if roomid else f"private_{sender}"
await self.redis_manager.remove_subscription(unique_id)
self.redis_manager.remove_subscription(unique_id)
await bot.send_text_message(roomid or sender, "✅ 已取消天气订阅。", sender)
return True, "取消成功"
@@ -263,7 +263,7 @@ class WeatherPlugin(MessagePluginInterface):
async def _execute_daily_push(self):
"""执行全量推送 (基于 ID 聚合)"""
self.LOG.info("🚀 执行每日推送...")
subs = await self.redis_manager.get_all_subscriptions()
subs = self.redis_manager.get_all_subscriptions()
if not subs: return
# 1. 按 [city_id] 聚合 (真正的去重)
@@ -289,7 +289,7 @@ class WeatherPlugin(MessagePluginInterface):
if not api_data: continue
# 获取 Redis 历史 (Key 也是 ID)
history_data = await self.redis_manager.get_history(city_id)
history_data = self.redis_manager.get_history(city_id)
# 生成文案
push_content = self._analyze_weather_change(city_name, api_data, history_data)
@@ -312,7 +312,7 @@ class WeatherPlugin(MessagePluginInterface):
self.LOG.error(f"推送给 {target_id} 失败: {send_e}")
# 存档
await self._save_today_as_history(city_id, api_data)
self._save_today_as_history(city_id, api_data)
except Exception as e:
self.LOG.error(f"处理城市ID {city_id} 推送失败: {e}")
@@ -464,7 +464,7 @@ class WeatherPlugin(MessagePluginInterface):
self.LOG.error(f"WeatherAPI(ID) 失败: {e}")
return None
async def _save_today_as_history(self, city_id: str, api_data: dict):
def _save_today_as_history(self, city_id: str, api_data: dict):
"""保存历史 (Key使用 ID)"""
if not self.redis_manager: return
try:
@@ -475,7 +475,7 @@ class WeatherPlugin(MessagePluginInterface):
"tempMin": today_fc['tempMin'],
"text": today_fc['textDay']
}
await self.redis_manager.save_history(city_id, data)
self.redis_manager.save_history(city_id, data)
except Exception as e:
self.LOG.error(f"存档失败: {e}")