feat: 添加中国节假日感知定时功能
- 新增 chinese_holidays 表,通过 timor.tech API 同步节假日数据 - 修正 holiday 字段解读:holiday=true → 休息日,holiday=false → 调休工作日 - 工作日 8:00-22:00 每小时爬取,周末/节假日/夜间自动跳过 - 新增 /api/v1/holidays/sync 和 /api/v1/holidays/today 接口 - 企微菜单新增「同步节假日」按钮,支持手动触发同步
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
|
||||
from app.config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MENU = {
|
||||
"button": [
|
||||
{
|
||||
"name": "今日公告",
|
||||
"type": "click",
|
||||
"key": "today_stats",
|
||||
},
|
||||
{
|
||||
"name": "系统管理",
|
||||
"sub_button": [
|
||||
{
|
||||
"name": "立即爬取",
|
||||
"type": "click",
|
||||
"key": "trigger_crawl",
|
||||
},
|
||||
{
|
||||
"name": "同步节假日",
|
||||
"type": "click",
|
||||
"key": "sync_holidays",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class MenuManager:
|
||||
def __init__(self, client=None):
|
||||
self.client = client
|
||||
|
||||
async def _get_token(self) -> str | None:
|
||||
from app.wechat.client import WeChatClient
|
||||
c = self.client or WeChatClient()
|
||||
return await c._get_access_token()
|
||||
|
||||
async def create(self) -> bool:
|
||||
token = await self._get_token()
|
||||
if not token:
|
||||
return False
|
||||
|
||||
url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create"
|
||||
params = {"access_token": token, "agentid": int(settings.wechat_agent_id)}
|
||||
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
response = await client.post(url, params=params, json=MENU)
|
||||
data = response.json()
|
||||
if data.get("errcode") == 0:
|
||||
logger.info("企微菜单创建成功")
|
||||
return True
|
||||
logger.error(f"企微菜单创建失败: {data}")
|
||||
return False
|
||||
|
||||
async def delete(self) -> bool:
|
||||
token = await self._get_token()
|
||||
if not token:
|
||||
return False
|
||||
|
||||
url = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete"
|
||||
params = {"access_token": token, "agentid": int(settings.wechat_agent_id)}
|
||||
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
response = await client.get(url, params=params)
|
||||
data = response.json()
|
||||
return data.get("errcode") == 0
|
||||
|
||||
async def get(self) -> dict | None:
|
||||
token = await self._get_token()
|
||||
if not token:
|
||||
return None
|
||||
|
||||
url = "https://qyapi.weixin.qq.com/cgi-bin/menu/get"
|
||||
params = {"access_token": token, "agentid": int(settings.wechat_agent_id)}
|
||||
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
response = await client.get(url, params=params)
|
||||
data = response.json()
|
||||
if data.get("errcode") == 0:
|
||||
return data
|
||||
return None
|
||||
Reference in New Issue
Block a user