feat: 添加飞书用户模块和订阅功能支持

- 新增feishu_users模块用于处理飞书用户身份验证和权限管理
- 新增subscriptions模块用于处理订阅相关功能
- 新增personalization模块用于个性化服务
- 在alembic迁移配置中注册新的模型模块
- 在API路由器中添加feishu_users和subscriptions路由
- 实现事件调度服务的改进,包括错误处理和状态更新优化
- 添加飞书命令处理的权限检查机制
- 实现飞书应用票据事件处理
- 改进审计日志记录功能
```
This commit is contained in:
2026-07-27 08:02:17 +08:00
parent db751f03b4
commit d7db84571d
148 changed files with 17110 additions and 765 deletions

View File

@@ -12,6 +12,7 @@ from app.tasks.constants import (
TASK_RUN_LIFECYCLE,
TASK_RUN_MARKET_CLOSE,
TASK_RUN_MARKET_REPORT,
TASK_RUN_SUBSCRIPTION_CYCLE,
)
from app.core.background.task_queue.dispatcher import dispatch_task
from app.core.background.task_queue.events import enqueue_event_dispatch
@@ -30,6 +31,7 @@ from app.core.background.task_queue.reports import (
enqueue_work_weekly_push,
)
from app.core.background.task_queue.risk import enqueue_risk_event_generation
from app.core.background.task_queue.subscriptions import enqueue_subscription_cycle
__all__ = [
@@ -46,6 +48,7 @@ __all__ = [
"TASK_RUN_LIFECYCLE",
"TASK_RUN_MARKET_CLOSE",
"TASK_RUN_MARKET_REPORT",
"TASK_RUN_SUBSCRIPTION_CYCLE",
"dispatch_task",
"enqueue_attendance_summary_push",
"enqueue_daily_brief_push",
@@ -58,6 +61,7 @@ __all__ = [
"enqueue_project_weekly_push",
"enqueue_risk_progress_push",
"enqueue_risk_event_generation",
"enqueue_subscription_cycle",
"enqueue_work_daily_push",
"enqueue_work_weekly_push",
]

View File

@@ -5,6 +5,7 @@ from app.core.config import get_settings
from app.core.constants import ActorValue
from app.core.database import SessionLocal
from app.application.pipelines import LifecyclePipelineService
from app.modules.workflows.constants import WorkflowStatus, WorkflowType
def enqueue_lifecycle_report(
@@ -28,16 +29,28 @@ def enqueue_lifecycle_report(
if get_settings().task_queue_enabled:
from app.tasks import celery_app
result = celery_app.signature(
TASK_RUN_LIFECYCLE,
kwargs={
"report_type": report_type,
"receive_id": receive_id,
"receive_id_type": receive_id_type,
"force": force,
"actor": actor,
},
).apply_async()
try:
result = celery_app.signature(
TASK_RUN_LIFECYCLE,
kwargs={
"report_type": report_type,
"receive_id": receive_id,
"receive_id_type": receive_id_type,
"force": force,
"actor": actor,
},
).apply_async()
except Exception as exc:
service.workflows.start_or_update(
workflow_type=WorkflowType.LIFECYCLE_REPORT,
aggregate_type="report_period",
aggregate_id=period_key,
status_value=WorkflowStatus.FAILED,
action="enqueue_failed",
actor=actor,
payload={"error": str(exc)[:2000]},
)
raise
return {
"workflow_code": workflow.code,
"period_key": period_key,

View File

@@ -1,5 +1,6 @@
from collections.abc import Callable
from typing import Any
from uuid import uuid4
from app.tasks.constants import (
TASK_PUSH_ATTENDANCE_SUMMARY,
@@ -173,37 +174,44 @@ def _queue_celery_report_push(
from app.modules.reports.services import ReportService
from app.tasks import celery_app
task_id = uuid4().hex
db = SessionLocal()
try:
push_run = ReportService(db).create_push_run(
service = ReportService(db)
push_run = service.create_push_run(
report_type=report_type,
title=title,
receive_id=receive_id,
receive_id_type=receive_id_type,
actor=actor,
status=ReportPushStatus.QUEUED,
task_id=task_id,
)
async_result = celery_app.signature(
task_name,
kwargs={
"receive_id": receive_id,
"receive_id_type": receive_id_type,
"actor": actor,
"push_run_code": push_run.code,
},
).apply_async()
ReportService(db).update_push_run(
push_run.code,
ReportPushStatus.QUEUED,
task_id=async_result.id,
)
try:
celery_app.signature(
task_name,
kwargs={
"receive_id": receive_id,
"receive_id_type": receive_id_type,
"actor": actor,
"push_run_code": push_run.code,
},
).apply_async(task_id=task_id)
except Exception as exc:
service.update_push_run(
push_run.code,
ReportPushStatus.FAILED,
task_id=task_id,
error_message=str(exc),
)
raise
finally:
db.close()
return {
"queued": True,
"mode": "celery",
"task_name": task_name,
"task_id": async_result.id,
"task_id": task_id,
"push_run_code": push_run.code,
}

View File

@@ -0,0 +1,14 @@
from app.application.delivery.subscriptions import run_subscription_cycle
from app.core.background.task_queue.dispatcher import dispatch_task
from app.core.constants import ActorValue
from app.tasks.constants import TASK_RUN_SUBSCRIPTION_CYCLE
def enqueue_subscription_cycle(
actor: str = ActorValue.SCHEDULER,
) -> dict:
return dispatch_task(
TASK_RUN_SUBSCRIPTION_CYCLE,
{"actor": actor},
lambda: run_subscription_cycle(actor=actor),
)