Files
arboris-novel/backend/app/services/update_log_service.py
2025-10-21 09:51:27 +08:00

61 lines
2.2 KiB
Python

from typing import List, Optional
from fastapi import HTTPException, status
from sqlalchemy import update
from sqlalchemy.ext.asyncio import AsyncSession
from ..models import UpdateLog
from ..repositories.update_log_repository import UpdateLogRepository
class UpdateLogService:
"""更新日志服务,提供增删改查能力,并保证置顶唯一。"""
def __init__(self, session: AsyncSession):
self.session = session
self.repo = UpdateLogRepository(session)
async def list_logs(self, limit: Optional[int] = None) -> List[UpdateLog]:
if limit is None:
return list(await self.repo.list())
return list(await self.repo.list_latest(limit))
async def create_log(self, content: str, creator: str | None = None, *, is_pinned: bool = False) -> UpdateLog:
if is_pinned:
await self._clear_pinned()
log = UpdateLog(content=content, created_by=creator, is_pinned=is_pinned)
await self.repo.add(log)
await self.session.commit()
await self.session.refresh(log)
return log
async def update_log(self, log_id: int, *, content: Optional[str] = None, is_pinned: Optional[bool] = None) -> UpdateLog:
log = await self.repo.get(id=log_id)
if not log:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="更新记录不存在")
updates = {}
if content is not None:
updates["content"] = content
if is_pinned is not None:
if is_pinned:
await self._clear_pinned()
updates["is_pinned"] = is_pinned
if updates:
await self.repo.update_fields(log, **updates)
await self.session.commit()
await self.session.refresh(log)
return log
async def delete_log(self, log_id: int) -> None:
log = await self.repo.get(id=log_id)
if not log:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="更新记录不存在")
await self.repo.delete(log)
await self.session.commit()
async def _clear_pinned(self) -> None:
await self.session.execute(update(UpdateLog).values(is_pinned=False))