feat(beatmap): 添加谱面用户标签功能 (#25)

* feat(tags): 添加 beatmap tags 相关功能

- 新增 BeatmapTags 模型类,用于表示 beatmap 的标签信息
- 实现加载标签数据、根据 ID 获取标签、获取所有标签等功能

* feat(database): 新增 BeatmapTagVote 数据库模型和迁移脚本

* fix(database): 修改 BeatmapTagVote 模型并创建新表

- 将 BeatmapTagVote 模型的表名从 "beatmap_tag_votes" 改为 "beatmap_tags"
- 创建新的数据库迁移文件以替换错误的原迁移文件
- 删除错误的迁移文件 "4a827ddba235_add_table_beatmap_tags.py"

* feat(tags): 添加用户标签功能

- 在 BeatmapResp 类中添加了 top_tag_ids 和 current_user_tag_ids 字段
- 新增了 /tags 相关的路由,包括获取所有标签和投票/取消投票功能
- 实现了标签投票和取消投票的数据库操作

* fix(tags): 修复标签投票查询和返回过程中的逻辑问题

- 修复 BeatmapResp 类中 current_user_tag_ids 字段的查询逻辑
- 优化 vote_beatmap_tags 函数中的标签验证过程

* fix(tags): add suggested changes from reviews

- 在 BeatmapResp 中添加 top_tag_ids 和 current_user_tag_ids 字段
- 实现用户标签投票功能,包括检查用户是否有资格投票
- 优化标签数据的加载方式
- 调整标签相关路由,增加路径参数描述

* fix(tags): apply changes from review

* fix(tag): apply changes from review suggests

- 更新标签接口文档,统一参数描述
- 修改标签投票接口状态码为 204
- 优化标签投票接口的用户认证方式
- 改进标签相关错误处理,使用更友好的错误信息

* fix(tag): use client authorization

* chore(linter): auto fix by pre-commit hooks

---------

Co-authored-by: MingxuanGame <MingxuanGame@outlook.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
陈晋瑭
2025-08-30 16:23:59 +08:00
committed by GitHub
parent d38cf12826
commit 6c2e88c485
7 changed files with 264 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
"""add beatmap_tag
Revision ID: ebaa317ad928
Revises: 24a32515292d
Create Date: 2025-08-29 12:29:23.267557
"""
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 = "ebaa317ad928"
down_revision: str | Sequence[str] | None = "24a32515292d"
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.create_table(
"beatmap_tags",
sa.Column("tag_id", sa.Integer(), nullable=False),
sa.Column("beatmap_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("tag_id", "beatmap_id", "user_id"),
)
op.create_index(op.f("ix_beatmap_tags_beatmap_id"), "beatmap_tags", ["beatmap_id"], unique=False)
op.create_index(op.f("ix_beatmap_tags_tag_id"), "beatmap_tags", ["tag_id"], unique=False)
op.create_index(op.f("ix_beatmap_tags_user_id"), "beatmap_tags", ["user_id"], unique=False)
op.drop_column("beatmapsets", "ratings")
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("beatmapsets", sa.Column("ratings", mysql.JSON(), nullable=True))
op.drop_index(op.f("ix_beatmap_tags_user_id"), table_name="beatmap_tags")
op.drop_index(op.f("ix_beatmap_tags_tag_id"), table_name="beatmap_tags")
op.drop_index(op.f("ix_beatmap_tags_beatmap_id"), table_name="beatmap_tags")
op.drop_table("beatmap_tags")
# ### end Alembic commands ###