hku-class-hub/backend/app/services/timeline_service.py
2026-04-11 12:52:23 +08:00

73 lines
2.0 KiB
Python

import json
from datetime import datetime
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.db.models import Timeline, User
from app.schemas.timeline import TimelineCreate, TimelineUpdate
async def create_timeline(
db: AsyncSession, class_id: int, author_id: int, data: TimelineCreate
) -> Timeline:
post = Timeline(
class_id=class_id,
author_id=author_id,
title=data.title,
content=data.content,
)
db.add(post)
await db.commit()
await db.refresh(post)
return post
async def update_timeline(
db: AsyncSession, post: Timeline, data: TimelineUpdate
) -> Timeline:
for field, value in data.model_dump(exclude_unset=True).items():
setattr(post, field, value)
await db.commit()
await db.refresh(post)
return post
async def delete_timeline(db: AsyncSession, post: Timeline):
await db.delete(post)
await db.commit()
async def get_timeline_by_id(db: AsyncSession, post_id: int) -> Timeline | None:
result = await db.execute(select(Timeline).where(Timeline.id == post_id))
return result.scalar_one_or_none()
async def list_timelines(
db: AsyncSession, class_id: int, page: int = 1, page_size: int = 20
) -> tuple[list[Timeline], int]:
total_result = await db.execute(
select(func.count(Timeline.id)).where(Timeline.class_id == class_id)
)
total = total_result.scalar() or 0
result = await db.execute(
select(Timeline)
.options(selectinload(Timeline.author))
.where(Timeline.class_id == class_id)
.order_by(Timeline.created_at.desc())
.offset((page - 1) * page_size)
.limit(page_size)
)
posts = list(result.scalars().all())
return posts, total
async def add_images_to_timeline(db: AsyncSession, post: Timeline, urls: list[str]):
existing = post.get_image_urls_list()
existing.extend(urls)
post.set_image_urls_list(existing)
await db.commit()
await db.refresh(post)