fix: 最新公告防重入覆盖整个函数,推送改为时间升序间隔1秒

- 防重入锁移到函数入口,60秒内重复点击直接忽略,避免企微重试导致重复推送
- 取最新6条后按 publish_date 升序推送,企微向上滑即为时间正序
- 每条间隔1秒发送

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 17:59:10 +08:00
parent c01a3d427b
commit 4f16134955
+11 -8
View File
@@ -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
try:
# 防重入:60秒内只爬取一次
# 防重入:60秒内整个函数只执行一次(含推送)
async with _latest_lock:
now = time.monotonic()
do_crawl = (now - _last_latest_time) >= 60
if do_crawl:
if (now - _last_latest_time) < 60:
logger.info("最新公告请求被忽略(防重入)")
return None
_last_latest_time = now
if do_crawl:
try:
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)