2026-03-20 15:15:35 +08:00
|
|
|
|
"""Celery:story 变更后重组关联章节的 canonical_markdown(物化视图)。"""
|
|
|
|
|
|
|
|
|
|
|
|
from celery import shared_task
|
|
|
|
|
|
from sqlalchemy import select
|
|
|
|
|
|
|
|
|
|
|
|
from app.core.db import get_sync_db
|
|
|
|
|
|
from app.core.logging import get_logger
|
|
|
|
|
|
from app.features.memoir import repo as memoir_repo
|
|
|
|
|
|
from app.features.memoir.models import Chapter, ChapterStoryLink
|
|
|
|
|
|
|
|
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task(bind=True, max_retries=3, default_retry_delay=30)
|
|
|
|
|
|
def recompose_chapters_for_story(self, story_id: str) -> dict:
|
|
|
|
|
|
try:
|
|
|
|
|
|
with get_sync_db() as session:
|
|
|
|
|
|
stmt = (
|
|
|
|
|
|
select(Chapter.id)
|
|
|
|
|
|
.join(
|
|
|
|
|
|
ChapterStoryLink,
|
|
|
|
|
|
ChapterStoryLink.chapter_id == Chapter.id,
|
|
|
|
|
|
)
|
|
|
|
|
|
.where(
|
|
|
|
|
|
ChapterStoryLink.story_id == story_id,
|
|
|
|
|
|
Chapter.markdown_compose_dirty.is_(True),
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
ids = list(session.scalars(stmt).all())
|
|
|
|
|
|
for cid in ids:
|
|
|
|
|
|
memoir_repo.compose_chapter_from_story_links_sync(session, cid)
|
|
|
|
|
|
session.commit()
|
|
|
|
|
|
logger.info(
|
2026-03-26 12:13:36 +08:00
|
|
|
|
"recompose_chapters_for_story: story={} recomposed_chapters={}",
|
2026-03-20 15:15:35 +08:00
|
|
|
|
story_id,
|
|
|
|
|
|
ids,
|
|
|
|
|
|
)
|
|
|
|
|
|
return {"story_id": story_id, "recomposed_chapter_ids": ids}
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
|
logger.warning(
|
2026-03-26 12:13:36 +08:00
|
|
|
|
"recompose_chapters_for_story failed story={} err={}", story_id, exc
|
2026-03-20 15:15:35 +08:00
|
|
|
|
)
|
|
|
|
|
|
raise self.retry(exc=exc) from exc
|