feat: initialize aivideo project

This commit is contained in:
2026-04-17 18:33:05 +08:00
commit 14b18d67fe
162 changed files with 26251 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.models.entities import InviteCode, InviteRelation, User
class InviteRepository:
def __init__(self, db: Session) -> None:
self.db = db
def get_default_code(self, user_id: int) -> InviteCode | None:
return self.db.scalar(
select(InviteCode).where(
InviteCode.user_id == user_id,
InviteCode.is_default.is_(True),
)
)
def get_code(self, code_value: str) -> InviteCode | None:
return self.db.scalar(select(InviteCode).where(InviteCode.invite_code == code_value))
def inviter_relations(self, user_id: int) -> list[InviteRelation]:
return (
self.db.query(InviteRelation)
.filter(InviteRelation.inviter_user_id == user_id)
.order_by(InviteRelation.id.desc())
.all()
)
def users_by_ids(self, user_ids: list[int]) -> dict[int, User]:
if not user_ids:
return {}
rows = self.db.scalars(select(User).where(User.id.in_(user_ids))).all()
return {row.id: row for row in rows}

View File

@@ -0,0 +1,43 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.common.db.session import get_db
from app.common.responses.api_response import success_response
from app.common.security.deps import get_current_user
from app.models.entities import User
from app.modules.invites.service import InviteService
router = APIRouter(prefix="/api/v1/invite", tags=["invite"])
@router.get("")
def get_invite_summary(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
return success_response(InviteService(db).get_invite_summary(current_user.id))
@router.post("/codes")
def create_invite_code(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
return success_response(InviteService(db).create_invite_code(current_user.id))
@router.get("/relations")
def list_relations(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
return success_response(InviteService(db).list_relations(current_user.id))
@router.get("/rewards")
def list_rewards(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
return success_response(InviteService(db).list_rewards(current_user.id))

View File

@@ -0,0 +1,6 @@
from pydantic import BaseModel
class CreateInviteCodeRequest(BaseModel):
regenerate: bool = False

View File

@@ -0,0 +1,75 @@
from sqlalchemy.orm import Session
from app.common.utils.id_gen import new_invite_code
from app.models.entities import InviteCode, InviteRelation
from app.modules.invites.repository import InviteRepository
class InviteService:
def __init__(self, db: Session) -> None:
self.db = db
self.repository = InviteRepository(db)
def get_invite_summary(self, user_id: int) -> dict:
code = self.repository.get_default_code(user_id)
if not code:
code = self._create_default_code(user_id)
relations = self.repository.inviter_relations(user_id)
rewarded = [item for item in relations if item.reward_status == "rewarded"]
return {
"inviteCode": code.invite_code,
"inviteLink": code.invite_link,
"invitedUsers": len(relations),
"rewardedUsers": len(rewarded),
"rewardedPoints": sum(item.reward_points for item in rewarded),
}
def create_invite_code(self, user_id: int) -> dict:
code = self.repository.get_default_code(user_id)
if code:
return {"inviteCode": code.invite_code, "inviteLink": code.invite_link}
code = self._create_default_code(user_id)
return {"inviteCode": code.invite_code, "inviteLink": code.invite_link}
def list_relations(self, user_id: int) -> list[dict]:
relations = self.repository.inviter_relations(user_id)
users = self.repository.users_by_ids([item.invitee_user_id for item in relations])
return [
{
"inviteeUserId": item.invitee_user_id,
"inviteeNickname": users.get(item.invitee_user_id).nickname if users.get(item.invitee_user_id) else "",
"rewardStatus": item.reward_status,
"rewardPoints": item.reward_points,
"createdAt": item.created_at.isoformat(),
"rewardedAt": item.rewarded_at.isoformat() if item.rewarded_at else None,
}
for item in relations
]
def list_rewards(self, user_id: int) -> list[dict]:
relations = self.repository.inviter_relations(user_id)
return [
{
"inviteeUserId": item.invitee_user_id,
"rewardStatus": item.reward_status,
"rewardPoints": item.reward_points,
"rewardedAt": item.rewarded_at.isoformat() if item.rewarded_at else None,
}
for item in relations
if item.reward_points > 0
]
def _create_default_code(self, user_id: int) -> InviteCode:
code_value = new_invite_code()
code = InviteCode(
user_id=user_id,
invite_code=code_value,
invite_link=f"http://localhost:3000/register?inviteCode={code_value}",
status=1,
is_default=True,
)
self.db.add(code)
self.db.commit()
self.db.refresh(code)
return code