fix(playlist): fix user attempts
This commit is contained in:
@@ -16,7 +16,11 @@ from .lazer_user import (
|
|||||||
UserResp,
|
UserResp,
|
||||||
)
|
)
|
||||||
from .multiplayer_event import MultiplayerEvent, MultiplayerEventResp
|
from .multiplayer_event import MultiplayerEvent, MultiplayerEventResp
|
||||||
from .playlist_attempts import ItemAttemptsCount, ItemAttemptsResp
|
from .playlist_attempts import (
|
||||||
|
ItemAttemptsCount,
|
||||||
|
ItemAttemptsResp,
|
||||||
|
PlaylistAggregateScore,
|
||||||
|
)
|
||||||
from .playlist_best_score import PlaylistBestScore
|
from .playlist_best_score import PlaylistBestScore
|
||||||
from .playlists import Playlist, PlaylistResp
|
from .playlists import Playlist, PlaylistResp
|
||||||
from .pp_best_score import PPBestScore
|
from .pp_best_score import PPBestScore
|
||||||
@@ -58,6 +62,7 @@ __all__ = [
|
|||||||
"OAuthToken",
|
"OAuthToken",
|
||||||
"PPBestScore",
|
"PPBestScore",
|
||||||
"Playlist",
|
"Playlist",
|
||||||
|
"PlaylistAggregateScore",
|
||||||
"PlaylistBestScore",
|
"PlaylistBestScore",
|
||||||
"PlaylistResp",
|
"PlaylistResp",
|
||||||
"Relationship",
|
"Relationship",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from .lazer_user import User, UserResp
|
from .lazer_user import User, UserResp
|
||||||
from .playlist_best_score import PlaylistBestScore
|
from .playlist_best_score import PlaylistBestScore
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
from sqlmodel import (
|
from sqlmodel import (
|
||||||
BigInteger,
|
BigInteger,
|
||||||
Column,
|
Column,
|
||||||
@@ -112,3 +113,39 @@ class ItemAttemptsResp(ItemAttemptsCountBase):
|
|||||||
resp.position = await item_attempts.get_position(session)
|
resp.position = await item_attempts.get_position(session)
|
||||||
# resp.accuracy *= 100
|
# resp.accuracy *= 100
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
class ItemAttemptsCountForItem(BaseModel):
|
||||||
|
id: int
|
||||||
|
attempts: int
|
||||||
|
passed: bool
|
||||||
|
|
||||||
|
|
||||||
|
class PlaylistAggregateScore(BaseModel):
|
||||||
|
playlist_item_attempts: list[ItemAttemptsCountForItem] = Field(default_factory=list)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_db(
|
||||||
|
cls,
|
||||||
|
room_id: int,
|
||||||
|
user_id: int,
|
||||||
|
session: AsyncSession,
|
||||||
|
) -> "PlaylistAggregateScore":
|
||||||
|
playlist_scores = (
|
||||||
|
await session.exec(
|
||||||
|
select(PlaylistBestScore).where(
|
||||||
|
PlaylistBestScore.room_id == room_id,
|
||||||
|
PlaylistBestScore.user_id == user_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).all()
|
||||||
|
playlist_item_attempts = []
|
||||||
|
for score in playlist_scores:
|
||||||
|
playlist_item_attempts.append(
|
||||||
|
ItemAttemptsCountForItem(
|
||||||
|
id=score.playlist_id,
|
||||||
|
attempts=score.attempts,
|
||||||
|
passed=score.score.passed,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return cls(playlist_item_attempts=playlist_item_attempts)
|
||||||
|
|||||||
@@ -62,20 +62,21 @@ async def process_playlist_best_score(
|
|||||||
)
|
)
|
||||||
).first()
|
).first()
|
||||||
if previous is None:
|
if previous is None:
|
||||||
score = PlaylistBestScore(
|
previous = PlaylistBestScore(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
score_id=score_id,
|
score_id=score_id,
|
||||||
room_id=room_id,
|
room_id=room_id,
|
||||||
playlist_id=playlist_id,
|
playlist_id=playlist_id,
|
||||||
total_score=total_score,
|
total_score=total_score,
|
||||||
)
|
)
|
||||||
session.add(score)
|
session.add(previous)
|
||||||
else:
|
elif not previous.score.passed or previous.total_score < total_score:
|
||||||
previous.score_id = score_id
|
previous.score_id = score_id
|
||||||
previous.total_score = total_score
|
previous.total_score = total_score
|
||||||
previous.attempts += 1
|
previous.attempts += 1
|
||||||
await session.commit()
|
await session.commit()
|
||||||
await redis.decr(f"multiplayer:{room_id}:gameplay:players")
|
if await redis.exists(f"multiplayer:{room_id}:gameplay:players"):
|
||||||
|
await redis.decr(f"multiplayer:{room_id}:gameplay:players")
|
||||||
|
|
||||||
|
|
||||||
async def get_position(
|
async def get_position(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
|
from app.database.playlist_attempts import PlaylistAggregateScore
|
||||||
from app.models.model import UTCBaseModel
|
from app.models.model import UTCBaseModel
|
||||||
from app.models.multiplayer_hub import ServerMultiplayerRoom
|
from app.models.multiplayer_hub import ServerMultiplayerRoom
|
||||||
from app.models.room import (
|
from app.models.room import (
|
||||||
@@ -23,6 +24,7 @@ from sqlmodel import (
|
|||||||
Relationship,
|
Relationship,
|
||||||
SQLModel,
|
SQLModel,
|
||||||
)
|
)
|
||||||
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||||
|
|
||||||
|
|
||||||
class RoomBase(SQLModel, UTCBaseModel):
|
class RoomBase(SQLModel, UTCBaseModel):
|
||||||
@@ -77,9 +79,16 @@ class RoomResp(RoomBase):
|
|||||||
playlist_item_stats: RoomPlaylistItemStats | None = None
|
playlist_item_stats: RoomPlaylistItemStats | None = None
|
||||||
difficulty_range: RoomDifficultyRange | None = None
|
difficulty_range: RoomDifficultyRange | None = None
|
||||||
current_playlist_item: PlaylistResp | None = None
|
current_playlist_item: PlaylistResp | None = None
|
||||||
|
current_user_score: PlaylistAggregateScore | None = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def from_db(cls, room: Room) -> "RoomResp":
|
async def from_db(
|
||||||
|
cls,
|
||||||
|
room: Room,
|
||||||
|
include: list[str] = [],
|
||||||
|
session: AsyncSession | None = None,
|
||||||
|
user: User | None = None,
|
||||||
|
) -> "RoomResp":
|
||||||
resp = cls.model_validate(room.model_dump())
|
resp = cls.model_validate(room.model_dump())
|
||||||
|
|
||||||
stats = RoomPlaylistItemStats(count_active=0, count_total=0)
|
stats = RoomPlaylistItemStats(count_active=0, count_total=0)
|
||||||
@@ -105,6 +114,10 @@ class RoomResp(RoomBase):
|
|||||||
resp.difficulty_range = difficulty_range
|
resp.difficulty_range = difficulty_range
|
||||||
resp.current_playlist_item = resp.playlist[-1] if resp.playlist else None
|
resp.current_playlist_item = resp.playlist[-1] if resp.playlist else None
|
||||||
|
|
||||||
|
if "current_user_score" in include and user and session:
|
||||||
|
resp.current_user_score = await PlaylistAggregateScore.from_db(
|
||||||
|
room.id, user.id, session
|
||||||
|
)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -116,13 +116,17 @@ async def get_room(
|
|||||||
room: int,
|
room: int,
|
||||||
category: str = Query(default=""),
|
category: str = Query(default=""),
|
||||||
db: AsyncSession = Depends(get_db),
|
db: AsyncSession = Depends(get_db),
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
redis: Redis = Depends(get_redis),
|
redis: Redis = Depends(get_redis),
|
||||||
):
|
):
|
||||||
# 直接从db获取信息,毕竟都一样
|
# 直接从db获取信息,毕竟都一样
|
||||||
db_room = (await db.exec(select(Room).where(Room.id == room))).first()
|
db_room = (await db.exec(select(Room).where(Room.id == room))).first()
|
||||||
if db_room is None:
|
if db_room is None:
|
||||||
raise HTTPException(404, "Room not found")
|
raise HTTPException(404, "Room not found")
|
||||||
return await RoomResp.from_db(db_room)
|
resp = await RoomResp.from_db(
|
||||||
|
db_room, include=["current_user_score"], session=db, user=current_user
|
||||||
|
)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/rooms/{room}", tags=["room"])
|
@router.delete("/rooms/{room}", tags=["room"])
|
||||||
|
|||||||
Reference in New Issue
Block a user