feat: 添加飞书用户模块和订阅功能支持 - 新增feishu_users模块用于处理飞书用户身份验证和权限管理 - 新增subscriptions模块用于处理订阅相关功能 - 新增personalization模块用于个性化服务 - 在alembic迁移配置中注册新的模型模块 - 在API路由器中添加feishu_users和subscriptions路由 - 实现事件调度服务的改进,包括错误处理和状态更新优化 - 添加飞书命令处理的权限检查机制 - 实现飞书应用票据事件处理 - 改进审计日志记录功能 ```
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
from sqlalchemy import select
|
|
from sqlalchemy.exc import IntegrityError
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.utils.time import utc_now
|
|
from app.modules.feishu.models import FeishuAppTicket
|
|
|
|
APP_TICKET_EVENT_TYPE = "app_ticket"
|
|
APP_TICKET_PAYLOAD_KEY = "app_ticket"
|
|
|
|
|
|
class FeishuAppTicketService:
|
|
"""Persist the latest ticket received through a verified Feishu event."""
|
|
|
|
def __init__(self, db: Session):
|
|
self.db = db
|
|
|
|
def get_ticket(self, app_id: str) -> str | None:
|
|
app_id_value = str(app_id).strip()
|
|
if not app_id_value:
|
|
return None
|
|
return self.db.scalar(
|
|
select(FeishuAppTicket.app_ticket).where(
|
|
FeishuAppTicket.app_id == app_id_value
|
|
)
|
|
)
|
|
|
|
def store_verified(self, app_id: str, ticket: str) -> FeishuAppTicket:
|
|
app_id_value = str(app_id).strip()
|
|
ticket_value = str(ticket).strip()
|
|
if not app_id_value or not ticket_value:
|
|
raise ValueError("Verified Feishu app ticket fields are required")
|
|
|
|
now = utc_now()
|
|
record = self.db.execute(
|
|
select(FeishuAppTicket)
|
|
.where(FeishuAppTicket.app_id == app_id_value)
|
|
.with_for_update()
|
|
).scalar_one_or_none()
|
|
if record is None:
|
|
record = FeishuAppTicket(
|
|
app_id=app_id_value,
|
|
app_ticket=ticket_value,
|
|
received_at=now,
|
|
updated_at=now,
|
|
)
|
|
try:
|
|
with self.db.begin_nested():
|
|
self.db.add(record)
|
|
self.db.flush()
|
|
except IntegrityError:
|
|
record = self.db.execute(
|
|
select(FeishuAppTicket)
|
|
.where(FeishuAppTicket.app_id == app_id_value)
|
|
.with_for_update()
|
|
).scalar_one()
|
|
|
|
record.app_ticket = ticket_value
|
|
record.received_at = now
|
|
record.updated_at = now
|
|
self.db.commit()
|
|
self.db.refresh(record)
|
|
return record
|