diff --git a/app/wechat/handler.py b/app/wechat/handler.py index f756465..31f201c 100644 --- a/app/wechat/handler.py +++ b/app/wechat/handler.py @@ -243,24 +243,25 @@ class WeChatMessageHandler: async def _handle_latest_announcements(self, from_user: str) -> str | None: global _last_latest_time from app.api.deps import get_db, get_crawl_service - from sqlalchemy import select, desc, or_ + from sqlalchemy import select, asc, or_ from app.models.announcement import Announcement + # 防重入:60秒内整个函数只执行一次(含推送) + async with _latest_lock: + now = time.monotonic() + if (now - _last_latest_time) < 60: + logger.info("最新公告请求被忽略(防重入)") + return None + _last_latest_time = now + try: - # 防重入:60秒内只爬取一次 - async with _latest_lock: - now = time.monotonic() - do_crawl = (now - _last_latest_time) >= 60 - if do_crawl: - _last_latest_time = now + await self.client.send_text("正在获取最新公告,请稍候...", from_user) + service = get_crawl_service() + await service.run_all() - if do_crawl: - await self.client.send_text("正在获取最新公告,请稍候...", from_user) - service = get_crawl_service() - await service.run_all() - - # 查:广西政采网关键词匹配 + 大化县政府网全部 + # 查:广西政采网关键词匹配 + 大化县政府网全部,取最新6条后按时间升序推送 async for db in get_db(): + from sqlalchemy import select, desc, or_ result = await db.execute( select(Announcement) .where(or_( @@ -276,7 +277,8 @@ class WeChatMessageHandler: await self.client.send_text("暂无公告", from_user) return None - for ann in items: + # 按时间升序推送,企微里向上滑即为时间正序 + for ann in sorted(items, key=lambda a: a.publish_date): title = ann.title if len(ann.title) <= 128 else ann.title[:125] + "..." purchase_name = ann.purchase_name or "" if len(purchase_name) > 25: @@ -285,6 +287,7 @@ class WeChatMessageHandler: source_name = ann.source_name or ann.source_code or "" description = f"{source_name} | {purchase_name} | {time_str}" await self.client.send_textcard(title, description, ann.content_url or "", from_user) + await asyncio.sleep(1) except Exception as e: logger.error(f"查询最新公告失败: {e}") await self.client.send_text("查询失败,请稍后再试", from_user)