## 全局接口规范与公共约定 所有 API 请求均基于 HTTP/1.1 或 HTTP/2 协议,遵循 RESTful 风格,数据交互格式严格使用 `application/json`。 ### 公共响应体 (Response Wrapper) 为便于前端统一封装 Axios 拦截器,所有接口统一返回以下基础结构: JSON ``` { "code": 200, // 业务状态码 (200: 成功, 4001: 参数错误, 4003: 无权限, 5000: 系统错误) "message": "Success", // 响应提示信息 "data": { ... }, // 核心业务数据,若无数据返回 null "timestamp": 1718181234 // 服务端响应时间戳 } ``` ### 鉴权机制 在 HTTP Header 中通过 `Authorization: Bearer ` 传递身份凭证。 ## 核心业务 API:代码提交与状态流转 由于代码编译、沙箱运行与 AI 评测属于耗时操作(数百毫秒至几十秒不等),系统必须采用**异步处理机制**。即:`提交接口 (POST)` 仅负责将任务压入队列并返回任务 ID,前端通过 `轮询接口 (GET)` 或 SSE/WebSocket 获取最终结果。 ### 1. 提交代码 (Submit Code) **`POST /api/v1/submissions`** **请求头:** ``` Content-Type: application/json ``` **请求参数 (Request Body):** JSON ``` { "question_id": "q-8848a", "contest_id": "c-1024", // 选填,若在考试/比赛中需携带 "language": "cpp", // 枚举值: cpp, java, python, arkts, sql, frontend_react 等 "code_content": { // 支持单文件或多文件工程(ArkTS 约定 main.ets) "main.cpp": "#include \nusing namespace std;\nint main() { cout << \"Hello\"; return 0; }" } } ``` *注:针对代码题,`code_content` 针对不同语言分别约定为 `main.cpp`、`Main.java`、`main.py`、`main.ets`(兼容 `main.ts`);针对前端题型可传入多文件键值对如 `{"index.html": "...", "styles.css": "...", "app.js": "..."}`。* **响应数据 (Response Data):** JSON ``` { "submission_id": "sub-9952xxyy", "status": "PENDING" } ``` ### 2. 获取评测结果与详情 (Poll Submission Status) **`GET /api/v1/submissions/{submission_id}`** **前端轮询策略建议:** 提交成功后,前端每隔 `1000ms`(算法题)或 `3000ms`(前端AI题)发起一次 GET 请求,直到返回的状态为终态(如 `ACCEPTED`, `WRONG_ANSWER` 等)停止轮询。 **响应数据 (状态流转中 - JUDGING):** JSON ``` { "submission_id": "sub-9952xxyy", "status": "JUDGING", "progress": { "total_cases": 10, "finished_cases": 4 // 用于前端渲染进度条 (OI/IOI模式) }, "result": null } ``` **响应数据 (评测结束 - ACCEPTED / WRONG_ANSWER):** JSON ``` { "submission_id": "sub-9952xxyy", "status": "WRONG_ANSWER", "result": { "score": 40, // 总得分 (适用于 OI 模式) "time_used_ms": 124, // 最大运行耗时 "memory_used_kb": 8192, // 最大内存消耗 "compile_error_log": null, // CE 状态下的编译报错信息 "test_cases_report": [ // 详细的用例通过情况 (可根据比赛权限决定是否脱敏隐藏) { "case_id": 1, "status": "ACCEPTED", "time_ms": 12, "memory_kb": 4096 }, { "case_id": 2, "status": "WRONG_ANSWER", "expected_output": "100", // 仅在练习模式下对用户可见 "actual_output": "99" } ], "ai_review_report": null // 仅前端 AI 题型有此节点 } } ``` **响应数据 (前端 AI 评测结束专属结果):** 当 `language` 为前端且状态完成时,`result.ai_review_report` 节点将包含 AI 结构化输出: JSON ``` "ai_review_report": { "ui_fidelity_score": 90, // UI 还原度得分 "code_quality_score": 85, // 代码质量得分 "comments": "组件拆分合理,但缺少了错误边界处理 (Error Boundary)。", "visual_diff_url": "https://oss.example.com/diff/sub-9952.png" // Playwright 视觉比对差异图 } ``` ## 系统核心枚举字典 (State Machine) `status` 字段严格遵守以下有限状态机流转。设计时需明确区分**非终态**与**终态**。 **非终态 (In-Progress States) - 需继续轮询:** - `PENDING`: 已压入消息队列,等待判题机拉取。 - `COMPILING`: 判题机已接单,正在编译代码。 - `JUDGING`: 编译成功,沙箱正在执行测试用例或进行 SQL 数据比对。 - `AI_REVIEWING`: (前端特有) Playwright 截图完成,正在等待大模型 API 结构化评分。 **终态 (Terminal States) - 停止轮询:** - `ACCEPTED` (AC): 答案完全正确。 - `WRONG_ANSWER` (WA): 输出与标准答案不符(或 SQL 结果集不符)。 - `TIME_LIMIT_EXCEEDED` (TLE): 运行超时。 - `MEMORY_LIMIT_EXCEEDED` (MLE): 内存超限。 - `RUNTIME_ERROR` (RE): 运行时崩溃(如数组越界、段错误、除零异常)。 - `COMPILE_ERROR` (CE): 编译失败(语法错误)。 - `SYSTEM_ERROR` (SE): 判题机内部故障(如沙箱穿透失败、Docker OOM、队列宕机),需联系管理员重测。 ## 性能优化建议与架构补充 当面临几千人同时在线笔试交卷的高并发场景时,单纯依靠 HTTP 轮询会产生极大的 Nginx 与网关压力。针对此系统,推荐以下进阶实现方案: 1. **Redis 状态缓存隔离**: 轮询接口 `GET /api/v1/submissions/{id}` **绝对不能直接打到 MySQL 数据库**。判题机在流转状态时,应将实时状态写入 Redis (`SETEX sub:status:{id} 3600 JSON`),轮询接口直接命中 Redis 内存返回,保障高并发下的极低延迟。 2. **SSE (Server-Sent Events) 替代长轮询**: 对于 AI 前端评测这种耗时可能长达 20-30 秒的场景,建议在 Web 端提交代码后,建立一条与服务端的 SSE 单向长链接 (`GET /api/v1/submissions/{id}/stream`)。判题结束时服务端主动向客户端推送 JSON 事件,彻底消除无效轮询带来的网络开销。 --- ## 开发者主页与用户档案子系统 API 个人主页支持本人自查与全平台跨用户互访(公开档案模式)。非敏感只读接口均支持可选的 `userId` 查询参数,缺省时默认为当前登录态用户。 ### 1. 查询用户主页基础资料 * **`GET /api/v1/users/profile`** * **请求参数 (Query Params):** `userId` (Long,可选,指定目标用户 ID;不填则返回当前用户) * **响应数据 (Data 节点):** ```json { "id": 27, "username": "zheco68", "email": "zheco@kece.local", "avatarUrl": "http://localhost:8080/uploads/avatars/27_abc.png", "bio": "专注于系统架构与高并发工程", "githubUrl": "https://github.com/zheco68", "roles": ["ADMIN"], "createdAt": "2026-10-10T12:00:00" } ``` ### 2. 更新个人资料(本人) * **`PUT /api/v1/users/profile`** * **请求头:** `Content-Type: application/json` * **请求体:** ```json { "bio": "更新个性签名", "githubUrl": "https://github.com/newlink", "avatarUrl": "http://localhost:8080/uploads/avatars/27_new.png" } ``` ### 3. 修改密码(本人) * **`PUT /api/v1/users/password`** * **请求体:** `{"oldPassword": "...", "newPassword": "..."}` ### 4. 头像文件上传(本人) * **`POST /api/v1/users/avatar`** * **请求头:** `Content-Type: multipart/form-data` * **约束与异常机制:** * 单文件限制 5MB,Spring Servlet 总请求限制 10MB。 * 超限触发全局异常处理器 `MaxUploadSizeExceededException`,返回友好业务状态码 `4001` 与明确提示,严禁抛出 500 系统错误。 * 成功返回生成的文件访问绝对 URL(如 `http://.../uploads/avatars/{userId}_{uuid}.ext`)。 ### 5. 52-周打卡热力图与连击统计 * **`GET /api/v1/users/profile/heatmap`** * **请求参数:** `userId` (Long,可选) * **响应数据:** ```json { "totalAc": 128, "currentStreak": 5, "maxStreak": 14, "dailyCounts": { "2026-03-01": 2, "2026-10-14": 4 } } ``` ### 6. 考试实战档案归档 * **`GET /api/v1/users/profile/exams`** * **请求参数:** `userId` (Long,可选) * **响应数据:** 返回数组,包含 `examId`、`title`、`mode` (ACM/OI)、`score`、`rank`、`totalParticipants`、`durationMinutes`、`submittedAt`。 ### 7. 跨用户全量提交记录查询 以下三个提交历史接口均已支持统一的 `userId` 筛选能力(开放访问): * **算法题提交:** `GET /api/v1/submissions?userId={id}&status={status}&page={page}&size={size}` * **数据库题提交:** `GET /api/v1/db-submissions?userId={id}&status={status}&page={page}&size={size}` * **客观题作答:** `GET /api/v1/objective-submissions?userId={id}&correct={0|1}&page={page}&size={size}` --- ## 核心业务 API:随堂课练与投屏互动 (Lesson Practice) 课练模块为教师课上练习、随堂小测与学生即时对拍提供一站式支持。支持 6 位大写口令免排课极速进房、全题型(客观题合卷 + 算法 OJ + 数据库 SQL OJ)以及课堂投屏监控大屏。 ### 1. 发起课练 (教师/管理员) * **`POST /api/v1/practice`** * **权限要求:** `TEACHER` 或 `ADMIN` * **请求体 (Request Body):** ```json { "title": "随堂算法与 SQL 实践", "description": "第 3 讲随堂小测,限时 45 分钟", "durationMinutes": 45, "questions": [ { "questionId": 1, "questionType": "OBJECTIVE", "score": 10, "sortOrder": 1 }, { "questionId": 1, "questionType": "ALGO", "score": 40, "sortOrder": 2 }, { "questionId": 1, "questionType": "DB", "score": 50, "sortOrder": 3 } ] } ``` * **响应数据:** 返回包含 6 位随机唯一 `accessCode`(如 `KE98A2`)及课练元数据的 `PracticeSummaryVO`。 ### 2. 课练列表分页查询 * **`GET /api/v1/practice?page={page}&size={size}`** * **响应数据:** 分页返回当前用户可见的课练列表、总人数、题量分布与个人作答简报。 ### 3. 通过口令加入课练 * **`POST /api/v1/practice/join`** * **请求体:** `{"accessCode": "KE98A2"}` * **业务逻辑:** 校验口令合法性与活动状态,原子化加入 `lesson_practice_member` 并初始化作答档案。 ### 4. 获取课练主页详情 * **`GET /api/v1/practice/{code}`** * **响应数据:** * 基础元数据:标题、教师姓名、口令、状态、剩余秒数 (`remainingSeconds`); * 个人态:`myJoined`、`myScore`、`mySolvedCount`、`mySubmitted`; * `objectiveQuestions`: 客观题列表(支持单选/多选/填空,包含题干、选项、分值及本人作答与得分); * `practicalQuestions`: 实战题列表(算法与 SQL 题,包含分值、时空限制、本人作答状态与提交 ID)。 ### 5. 客观题集中答题并批量即时判分 (Unified Objective Submit) * **`POST /api/v1/practice/{code}/objective-submit`** * **请求体:** ```json { "answers": { "4": "C", "5": "A,B" } } ``` *(注:Key 为 `practiceQuestionId`,Value 为答案字符串;单选/填空为单值,多选为英文逗号分隔字母)* * **响应数据:** ```json { "totalScore": 20, "fullScore": 20, "correctCount": 1, "totalCount": 1, "items": [ { "practiceQuestionId": 4, "questionId": 1, "correct": true, "score": 20, "fullScore": 20, "userAnswer": "C", "correctAnswer": "C" } ] } ``` ### 6. 实战题(算法/SQL)作答同步 * **`POST /api/v1/practice/{code}/practical-record`** * **请求体:** ```json { "practiceQuestionId": 2, "submissionId": 1024, "questionType": "ALGO", "status": "ACCEPTED", "score": 40 } ``` * **业务逻辑:** 记录本次实战提交,自动重新汇总并更新该学生在当前课练的总积分与 AC 题数。 ### 7. 学生整场交卷确认 * **`POST /api/v1/practice/{code}/submit`** * **业务逻辑:** 锁定该学生在当前课练的提交权限,置 `submitted = 1`,归档成绩。 ### 8. 教师课堂投屏监控大屏数据 (Projector Dashboard) * **`GET /api/v1/practice/{code}/monitor`** * **权限要求:** `TEACHER` 或 `ADMIN` * **响应数据:** * `accessCode`: 6 位发光展示口令; * `status`: `ACTIVE` / `ENDED`; * `remainingSeconds`: 实时剩余秒数; * 课堂 Bento 指标:`totalStudents`、`submittedCount`、`averageScore`、`objectivePassRate`; * `questionStats`: 各题总提交数、通过人数及通过率百分比横条; * `latestSubmissions`: 实时提交气泡流(最近 15 条作答流水); * `leaderboard`: 全班排名榜单(支持前端一键姓名脱敏)。 ### 9. 教师课上控制:快速延时与提前收卷 * **`POST /api/v1/practice/{code}/extend`**:`{"extraMinutes": 5}`,自动顺延结束时间; * **`POST /api/v1/practice/{code}/end`**:提前截止收卷,置 `status = 'ENDED'`。 --- ## 全站 UI 视觉与纯色规范体系 (Design System) KECE 统一采用 **Modern Brutalist(现代极客新野兽派)** 工业设计语言,杜绝发灰、泛白的低饱和半透明水洗色,全部使用硬朗直角(`border-radius: 0`)与高反差实心纯色填充。 ### 1. 身份角色色彩规范 | 角色 | 中文名 | 实心背景色 (Hex) | 字体色 | 边框色 | 适用场景 | |---|---|---|---|---|---| | `ADMIN` | 管理员 | `#7048e8` (纯紫) | `#ffffff` | `#5f3dc4` | 顶栏用户卡片、个人名片徽标 | | `TEACHER` | 教师 | `#2b8a3e` (纯绿) | `#ffffff` | `#237032` | 顶栏用户卡片、个人名片徽标 | | `USER` | 学生 | `#1e1e1e` (纯黑) | `#ffffff` | `#111111` | 顶栏用户卡片、个人名片徽标 | ### 2. 题目难度色彩规范 | 难度 | 级别 | 实心背景色 (Hex) | 字体色 | 边框色 | 交互说明 | |---|---|---|---|---|---| | `EASY` | 简单 | `#2b8a3e` (实心绿) | `#ffffff` | `#237032` | 题库卡片、工具栏激活态 | | `MEDIUM` | 中等 | `#e67700` (实心橙) | `#ffffff` | `#c96500` | 题库卡片、工具栏激活态 | | `HARD` | 困难 | `#c92a2a` (实心红) | `#ffffff` | `#b02525` | 题库卡片、工具栏激活态 | ### 3. 数据库题型黑灰极简规范 为避免“红蓝冲突”带来的不适,数据库题型遵循严谨的工业冷黑灰配色: * **`SELECT 查询`(读操作)**: 纯黑实心底 `#1e1e1e`,纯白文字,边框 `#111111`。 * **`DML 操作`(写操作)**: 钛金深灰实心底 `#495057`,纯白文字,边框 `#343a40`。 ### 4. 交互与动效规范 * **顶栏导航跟随滑块 (Hover Slider)**: * 鼠标未悬停时仅高亮当前路由,菜单文字保持纯净(无杂乱 Emoji 与小图标); * 鼠标悬停进入时在菜单下方动态展开 **34px 纯直角灰色方块**(`#ececec`),移动时使用 `cubic-bezier(0.16, 1, 0.3, 1)` 曲线平滑滑动跟随,移出后平滑隐去。 * **题卡信息与无 Emoji 规范**: * 严禁在正式规格参数中使用表情符号; * 时空限制统一使用标准等宽文本:如 `1000ms / 256MB`; * 支持编程语言统一格式化标准名称(如 `C++`、`Java`、`Python`)。