# aigd100 **Repository Path**: sushile/aigd100 ## Basic Information - **Project Name**: aigd100 - **Description**: aigd100-backed - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-26 - **Last Updated**: 2026-01-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AIGD100 API 一个基于 FastAPI 的竞赛与参赛作品管理系统,集成用户认证、作品管理、评分维度与规则、外部社交数据抓取(抖音)等功能,提供完整的后台管理与参赛端接口。 ## 项目概述 - 主要功能 - 比赛管理:创建、更新、统计、排名、评委配置 - 作品管理:创建、发布/草稿切换、审核、置顶、评分、评论、外部链接审核与抓取 - 评分体系:评分维度与规则管理、评委维度评分与聚合统计 - 社交抓取:抖音视频互动数据与评论抓取(Playwright),入库并展示 - 等级积分:用户等级与奖励积分管理 - 技术栈 - 后端框架:FastAPI - 数据库与 ORM:MySQL + SQLAlchemy - 身份认证:JWT(`utils/auth.py`) - 数据验证:Pydantic - 抓取框架:Playwright(Headless Chromium) - 其他:aiofiles、Pillow(上传图片处理) ```mermaid flowchart LR A[Client / Admin] -->|HTTP| B[FastAPI Routers] B --> C[Competition / Works / Score / Social Links / Levels] C --> D[(MySQL / SQLAlchemy)] B --> E[BackgroundTasks] E --> F[Playwright (Douyin)] F --> D ``` ## 接口说明 说明遵循统一响应结构:`{ code, msg, data }`。所有受保护接口需在请求头附带 `Authorization: Bearer `。 - 比赛管理(`routers/competition.py`) - 获取评分维度与规则(全部) - 方法:`GET` - 路径:`/competitions/score-rules` - 返回示例:包含维度列表与对应规则,参见代码 `routers/competition.py:57` 的结构化返回 - 按评分状态查询作品 - 方法:`GET` - 路径:`/competitions/{competition_id}/works/score-status` - 参数:`type`(未评分/已评分/全部)、`pageNum`、`pageSize` - 返回:比赛信息与分页作品列表、`avg_score`、`judge_count` - 获取比赛排名 - 方法:`GET` - 路径:`/competitions/{competition_id}/ranking` - 排序:审核通过作品,按 `work_score` 与 `work_like` 降序 - 获取比赛统计 - 方法:`GET` - 路径:`/competitions/{competition_id}/stats` - 返回:作品总数、审核通过/待审核数量、参赛用户数等 - 更新作品发布状态(草稿/发布切换) - 方法:`PUT` - 路径:`/competitions/works/{work_id}/release-status` - 请求体:`{ "target_status": 1 | 2, "reason": string? }` - 规则:`2->1` 发布前校验比赛未结束;`1->2` 草稿时清空维度评分与总分 - 外部社交链接与抖音抓取(`routers/social_links.py`) - 创建外部链接审核记录 - 方法:`POST` - 路径:`/competitions/works/{work_id}/links/audits` - 请求体:`{ "work_id": number, "platform": "douyin", "url": string }` - 返回:审核记录 - 更新外部链接审核状态并触发爬虫 - 方法:`PUT` - 路径:`/competitions/links/audits` - 规则:当 `status=2` 且平台为 `douyin` 时,触发后台任务抓取互动数据与 Top5 评论 - 查询外部评论 Top5 - 方法:`GET` - 路径:`/competitions/works/{work_id}/social-comments` - 参数:`platform`(默认 `douyin`) - 返回:Top5 评论列表(入库顺序) - 评分维度与规则(`routers/score_dimensions.py`) - 获取维度列表 - 方法:`GET` - 路径:`/score-dimensions/get` - 参数:`page`、`size`、`keyword`、`dimension_name` - 创建维度(管理员) - 方法:`POST` - 路径:`/score-dimensions/add` - 请求体:`ScoreDimensionCreate` - 维度详情 - 方法:`GET` - 路径:`/score-dimensions/{dimension_id}` - 更新维度(管理员) - 方法:`PUT` - 路径:`/score-dimensions/{dimension_id}` - 等级积分管理(`routers/levels.py`) - 获取用户等级列表 - 方法:`GET` - 路径:`/levels/user-levels` - 参数:`page`、`size`、`keyword` - 创建用户等级(管理员) - 方法:`POST` - 路径:`/levels/user-levels` - 请求体:`UserLevelCreate` - 用户等级详情 - 方法:`GET` - 路径:`/levels/user-levels/{level_id}` 更多认证与上传接口可通过 Swagger UI 查看:`/docs`。 ## 环境配置 - 开发环境 - Python 3.8+ - MySQL 5.7+ - 依赖安装:`pip install -r requirements.txt` - Playwright 安装:`pip install playwright && python -m playwright install` - 启动:`python main.py`(默认 `http://localhost:8000`) - 测试环境 - 使用独立数据库(避免污染生产数据) - 运行接口测试集合(Postman/Insomnia),设置 `{{baseUrl}}` 与 `{{token}}` - 可选:开启 `uvicorn` 多进程与日志聚合 - 生产环境 - WSGI/ASGI 部署:`uvicorn` 或 `gunicorn + uvicorn workers` - 环境变量 - `DATABASE_URL`:`mysql+pymysql://username:password@host:port/aigd100` - `SECRET_KEY`、`ALGORITHM`、`ACCESS_TOKEN_EXPIRE_MINUTES` - 爬虫相关可选:`DY_PHONE`、`DY_PASSWORD`(若启用登录方式) - 注意事项 - 修改默认 `SECRET_KEY` - 配置 HTTPS 与 CORS - 数据库账号权限最小化、定期备份 - 监控后台任务与抓取失败重试 ## 开发指南 - 代码规范 - Python 版本统一,PEP8 代码风格 - 函数级注释必填(入参/返回/说明) - 路由统一返回 `{code, msg, data}` - 分支策略 - `main`:稳定分支 - `develop`:集成分支 - `feature/*`:功能分支 - `hotfix/*`:紧急修复 - CI/CD 流程(建议) - 安装依赖 → Lint/Type Check → 单元测试 → 构建 → 部署 - 失败时阻断合并,产出报告 ## 接口测试用例 - Postman 集合文件:`docs/api-tests.postman_collection.json` - 变量 - `baseUrl`:默认 `http://localhost:8000` - `token`:登录后填充 - 覆盖接口 - 比赛评分规则获取 - 评分状态查询作品 - 比赛排名与统计 - 作品发布状态切换 - 链接审核创建/更新与评论查询 - 评分维度列表/新增/详情/更新 - 用户等级列表/新增/详情 ## 代码示例 ```python import requests BASE = "http://localhost:8000" TOKEN = "Bearer " headers = {"Authorization": TOKEN} # 发布作品 resp = requests.put( f"{BASE}/competitions/works/123/release-status", json={"target_status": 1}, headers=headers ) print(resp.json()) ``` ## 版本更新日志 - v1.1.0(2025-12-17) - 新增:作品发布状态切换接口(草稿 ↔ 发布) - 重构:抖音抓取改为 Playwright 页面解析并入库 Top5 评论 - 文档:重写 README,补充测试集合与架构图 - v1.0.0(2024-01-XX) - 初始版本发布:认证与上传基础能力、API 文档与测试、数据库初始化