feat(score): add best_id in response
This commit is contained in:
@@ -58,7 +58,6 @@ class ScoreBase(SQLModel):
|
|||||||
# 基本字段
|
# 基本字段
|
||||||
accuracy: float
|
accuracy: float
|
||||||
map_md5: str = Field(max_length=32, index=True)
|
map_md5: str = Field(max_length=32, index=True)
|
||||||
best_id: int | None = Field(default=None)
|
|
||||||
build_id: int | None = Field(default=None)
|
build_id: int | None = Field(default=None)
|
||||||
classic_total_score: int | None = Field(
|
classic_total_score: int | None = Field(
|
||||||
default=0, sa_column=Column(BigInteger)
|
default=0, sa_column=Column(BigInteger)
|
||||||
@@ -130,7 +129,9 @@ class Score(ScoreBase, table=True):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
if with_user:
|
if with_user:
|
||||||
clause.options(joinedload(Score.user).options(*User.all_select_option())) # pyright: ignore[reportArgumentType]
|
return clause.options(
|
||||||
|
joinedload(Score.user).options(*User.all_select_option()) # pyright: ignore[reportArgumentType]
|
||||||
|
)
|
||||||
return clause
|
return clause
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -168,6 +169,7 @@ class ScoreResp(ScoreBase):
|
|||||||
legacy_total_score: int = 0 # FIXME
|
legacy_total_score: int = 0 # FIXME
|
||||||
processed: bool = False # solo_score
|
processed: bool = False # solo_score
|
||||||
weight: float = 0.0
|
weight: float = 0.0
|
||||||
|
best_id: int | None = None
|
||||||
ruleset_id: int | None = None
|
ruleset_id: int | None = None
|
||||||
beatmap: BeatmapResp | None = None
|
beatmap: BeatmapResp | None = None
|
||||||
beatmapset: BeatmapsetResp | None = None
|
beatmapset: BeatmapsetResp | None = None
|
||||||
@@ -190,8 +192,10 @@ class ScoreResp(ScoreBase):
|
|||||||
s.is_perfect_combo = s.max_combo == s.beatmap.max_combo
|
s.is_perfect_combo = s.max_combo == s.beatmap.max_combo
|
||||||
s.legacy_perfect = s.max_combo == s.beatmap.max_combo
|
s.legacy_perfect = s.max_combo == s.beatmap.max_combo
|
||||||
s.ruleset_id = MODE_TO_INT[score.gamemode]
|
s.ruleset_id = MODE_TO_INT[score.gamemode]
|
||||||
if score.best_id:
|
best_id = await get_best_id(session, score.id)
|
||||||
s.weight = calculate_pp_weight(score.best_id)
|
if best_id:
|
||||||
|
s.best_id = best_id
|
||||||
|
s.weight = calculate_pp_weight(best_id - 1)
|
||||||
s.statistics = {
|
s.statistics = {
|
||||||
HitResult.MISS: score.nmiss,
|
HitResult.MISS: score.nmiss,
|
||||||
HitResult.MEH: score.n50,
|
HitResult.MEH: score.n50,
|
||||||
@@ -224,7 +228,7 @@ class ScoreResp(ScoreBase):
|
|||||||
score.map_md5,
|
score.map_md5,
|
||||||
score.id,
|
score.id,
|
||||||
mode=score.gamemode,
|
mode=score.gamemode,
|
||||||
user=score.user,
|
user=user or score.user,
|
||||||
)
|
)
|
||||||
or None
|
or None
|
||||||
)
|
)
|
||||||
@@ -234,13 +238,25 @@ class ScoreResp(ScoreBase):
|
|||||||
score.map_md5,
|
score.map_md5,
|
||||||
score.id,
|
score.id,
|
||||||
score.gamemode,
|
score.gamemode,
|
||||||
score.user,
|
user or score.user,
|
||||||
)
|
)
|
||||||
or None
|
or None
|
||||||
)
|
)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
async def get_best_id(session: AsyncSession, score_id: int) -> None:
|
||||||
|
rownum = (
|
||||||
|
func.row_number()
|
||||||
|
.over(partition_by=col(BestScore.user_id), order_by=col(BestScore.pp).desc())
|
||||||
|
.label("rn")
|
||||||
|
)
|
||||||
|
subq = select(BestScore, rownum).subquery()
|
||||||
|
stmt = select(subq.c.rn).where(subq.c.score_id == score_id)
|
||||||
|
result = await session.exec(stmt)
|
||||||
|
return result.one_or_none()
|
||||||
|
|
||||||
|
|
||||||
async def get_leaderboard(
|
async def get_leaderboard(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
beatmap_md5: str,
|
beatmap_md5: str,
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""score: remove best_id in database
|
||||||
|
|
||||||
|
Revision ID: 78be13c71791
|
||||||
|
Revises: dc4d25c428c7
|
||||||
|
Create Date: 2025-07-29 07:57:33.764517
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "78be13c71791"
|
||||||
|
down_revision: str | Sequence[str] | None = "dc4d25c428c7"
|
||||||
|
branch_labels: str | Sequence[str] | None = None
|
||||||
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column("scores", "best_id")
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column(
|
||||||
|
"scores",
|
||||||
|
sa.Column("best_id", mysql.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
Reference in New Issue
Block a user