# API 参考(v1) 统一前缀:`/api/v1` > Docker/生产推荐通过前端同域反代访问:`/admin139/api/v1/...` ## 通用约定 - 鉴权头(二选一): - `Authorization: Bearer `(推荐) - `Authorization: Basic `(第三方直连更方便) - 成功响应:`{ "ok": true, "data": ... }`(Auth 接口除外) - 失败响应:`{ "ok": false, "error": "..." }` ### 第三方接入快速示例 1) 登录拿 token(Bearer 方式) ```bash curl -X POST 'https://csp.hao.work/admin139/api/v1/auth/login' \ -H 'Content-Type: application/json' \ -d '{"username":"alice","password":"password123"}' ``` 2) Bearer 调用 ```bash curl 'https://csp.hao.work/admin139/api/v1/me' \ -H 'Authorization: Bearer ' ``` 3) Basic 直接调用 ```bash curl 'https://csp.hao.work/admin139/api/v1/me' \ -H 'Authorization: Basic YWxpY2U6cGFzc3dvcmQxMjM=' ``` > `YWxpY2U6cGFzc3dvcmQxMjM=` 是 `alice:password123` 的 Base64。 --- ## 1) Auth ### `POST /auth/register` 请求: ```json { "username": "alice", "password": "password123" } ``` 响应: ```json { "ok": true, "user_id": 1, "token": "...", "expires_at": 1730000000 } ``` ### `POST /auth/login` 请求同上,响应同上。 --- ## 2) 用户与排行榜 ### `GET /me`(需鉴权) 返回当前用户信息。 ### `GET /leaderboard/global?limit=100` 返回全站 rating 排行。 --- ## 3) 题库 ### `GET /problems?q=&tag=&difficulty=&page=&page_size=` 返回题目列表。 ### `GET /problems/:id` 返回题目详情。`Problem` 结构包含: - `statement_url`:原始 PDF 链接 - `llm_profile_json`:固定 JSON 字符串(`title/difficulty/answer/explanation/knowledge_points/tags/...`) --- ## 4) 提交与在线运行 ### `POST /problems/:id/submit`(需鉴权) 请求: ```json { "language": "cpp", "code": "#include ...", "contest_id": 1 } ``` - `contest_id` 可选;若提交到比赛,需已报名且比赛进行中。 ### `GET /submissions?user_id=&problem_id=&contest_id=&created_from=&created_to=&page=&page_size=` 返回提交列表。 ### `GET /submissions/:id` 返回提交详情(含代码、编译日志、运行日志)。 ### `POST /run/cpp` 请求: ```json { "code": "...", "input": "1 2\n" } ``` 返回:运行状态、stdout/stderr、compile_log。 --- ## 5) 错题本 ### `GET /me/wrong-book`(需鉴权) 返回当前用户错题本。 ### `PATCH /me/wrong-book/:problemId`(需鉴权) 请求: ```json { "note": "复盘思路" } ``` ### `DELETE /me/wrong-book/:problemId`(需鉴权) 删除错题项。 --- ## 6) 模拟竞赛 ### `GET /contests` 返回比赛列表。 ### `GET /contests/:id` 返回比赛详情与题单;若请求带 token,还会返回 `registered`。 ### `POST /contests/:id/register`(需鉴权) 报名比赛。 ### `GET /contests/:id/leaderboard` 比赛排行榜(按 solved desc, penalty asc)。 --- ## 7) 学习知识库 ### `GET /kb/articles` 返回知识库文章列表。 ### `GET /kb/articles/:slug` 返回文章详情与关联题目。 ### `GET /kb/articles/:slug/claims`(需鉴权) 返回当前用户在该文章下已领取知识点和累计积分。 ### `POST /kb/articles/:slug/claim`(需鉴权) 请求: ```json { "knowledge_key": "cpp14-io-01" } ``` 说明: - 有前置依赖的知识点,若前置未完成会返回 400。 - 同一知识点不可重复领取积分。 ### `GET /kb/weekly-plan`(需鉴权) 返回本周自动生成的学习任务(含完成度、奖励汇总)。 ### `POST /kb/weekly-bonus/claim`(需鉴权) 领取本周任务 100% 完成奖励;未达 100% 返回 400。 --- ## 8) 题库导入任务(PDF + LLM) ### `GET /import/jobs/latest` 返回最近一次导入任务及运行状态(`runner_running`)。 ### `GET /import/jobs/:id` 返回指定导入任务详情。 ### `GET /import/jobs/:id/items?status=&page=&page_size=` 返回任务明细(每个 PDF 的处理状态、结果或错误)。 ### `POST /import/jobs/run` 手动触发导入任务(若已有运行中的任务会返回 `409`)。 请求体(可选): ```json { "clear_all_problems": true } ``` 也支持本地 PDF + RAG + LLM 出题模式(异步执行,进度同样写入 `import_jobs/import_job_items`): ```json { "mode": "local_pdf_rag", "workers": 3, "local_pdf_dir": "/data/local_pdfs", "target_total": 5000 } ``` --- ## 9) 后台日志(题解异步队列) ### `GET /backend/logs?limit=100` 返回最近题解生成任务日志(按任务 ID 倒序),并包含当前排队任务数 `pending_jobs`。 ### `GET /backend/db-lock-guard/status`(需管理员鉴权) 返回 SQLite 锁守护运行状态,字段包含: - `enabled` / `started`:守护是否启用、是否已启动 - `interval_sec` / `probe_busy_timeout_ms`:探测间隔与超时 - `busy_streak` / `busy_streak_trigger`:当前连续锁冲突计数与触发阈值 - `last_probe_at` / `last_probe_rc` / `last_probe_error`:最近探测结果 - `last_repair_at` / `repair_count`:最近一次自愈时间与累计自愈次数 --- ## 10) 网站爬虫列表(管理员) ### `GET /admin/crawlers?status=&limit=` 返回爬虫目标列表(按最新倒序)。 ### `POST /admin/crawlers` 手动新增爬虫目标。请求体示例: ```json { "url": "https://example.com" } ``` ### `POST /admin/crawlers/:id/queue` 将目标重新入队,触发“规则生成 -> 自动测试 -> 自动运行”流程。 ### `GET /admin/crawlers/:id/runs?limit=20` 查看指定目标的运行记录。 ### `GET /backend/crawler-guard/status`(需管理员鉴权) 返回爬虫守护进程状态(是否启用、是否运行、处理统计、最近错误等)。 - `active_requeue_interval_sec` 表示活跃目标的周期重跑间隔(秒,默认 43200 即 12 小时)。 > 飞书群内 `@机器人` 文本如果包含 URL,也会自动写入爬虫目标列表并触发守护流程。 --- ## 11) Lark 机器人事件回调 ### `POST /lark/events` 用于飞书(Lark)事件订阅回调,支持: - URL 验证:请求体带 `challenge` 时回传 `{ "challenge": "..." }` - 消息事件:处理 `im.message.receive_v1` 文本消息并异步回复 环境变量(后端): - `CSP_LARK_BOT_ENABLED=true`:是否启用机器人 - `CSP_LARK_VERIFICATION_TOKEN=...`:事件回调 token(可选,建议配置) - `CSP_LARK_APP_ID=...` / `CSP_LARK_APP_SECRET=...`:飞书应用凭据 - `CSP_LARK_OPEN_BASE_URL=https://open.feishu.cn`:飞书 OpenAPI 域名 - `CSP_LARK_LLM_API_URL=...` / `CSP_LARK_LLM_API_KEY=...` / `CSP_LARK_LLM_MODEL=...`:对话模型配置 - 可选:`CSP_LARK_LLM_SYSTEM_PROMPT`、`CSP_LARK_MEMORY_TURNS`、`CSP_LARK_MAX_REPLY_CHARS`