Skip to content

TwinklerG/supercode-doc

Repository files navigation

Supercode

需求文档

架构图

---
title: 架构图
---
architecture-beta
    service top_gateway(internet)[Gateway]
    service server(server)[Server]
    service runner1(server)[Runner1]
    service runner2(server)[Runner2]
    service disk(disk)[Disk]
    top_gateway:B --> T:server
    server:B -- T:runner1
    server:L -- R:runner2
    server:R --> L:disk
Loading
architecture-beta
		service server(server)[Server]
		service redis(disk)[Redis]
		service runnerx(server)[Runnerx]
		server:R --> L:runnerx
		runnerx:B -- T:redis
    redis:T -- B:server
Loading

用户管理

用户表

字段 数据类型 描述
uid auto_generate 用户唯一标识
username String(unique, not null) 用户名
password String(not null) 密码
nickname String(not null) 用户昵称
email String(not null) 邮箱
role String 用户身份

用户身份:超级管理员,管理员,普通用户

超级管理员

别名:root

简介:这是系统创建时自动创建的初始管理员,拥有最高权力

超级管理员可以获取、新建、删除和修改所有用户信息,

管理员

别名:admin

简介:管理员身份由超级管理员赋予普通用户,也可被超级管理员降级为普通用户

管理员可以获取、新建所有用户信息,管理员可以修改和删除普通用户的信息。

普通用户

别名:user

简介:普通用户由管理员/超级管理员创建,可以修改自己的信息(uuid, role字段除外)

代码评测

评测记录表

字段 数据类型 描述
submission_id auto_generate 提交记录唯一标识
user_id foreign_key 提交用户唯一标识
problem_id foreign_key 题目唯一标识
language String(枚举类) 编程语言
code String 代码
time Int 运行时间
memory Int 内存占用
result String(枚举类Serialize) 评测结果
stdio List<Tuple<String, String, String>> 标准输入,输出,错误输出
submission_time 提交时间

题目内容表

字段 数据类型 描述
uuid auto_generate 题目唯一标识
title String 标题
description String 描述
time_limit Int 时间限制
time_reserved Int 时间保留限制
memory_limit Int 内存限制
memory_reserved Int 内存保留限制
large_stack Boolean 是否开大栈
output_limit Int 输出行数限制(0为无限制)
process_limit Int 进程限制(0为无限制)
example_stdio List<Tuple<String, String, String>> 样例标准输入,输出,错误输出
stdio List<Tuple<String, String, String>> 测试点标准输入,输出,错误输出

超级管理员,管理员,普通用户均可以提交代码进行评测

代码评测作为Runner分布式地部署在不同服务器的不同端口。对于编译型语言,在本机进行编译和构建,然后使用docker运行;对于解释型语言,直接在docker运行。

限制每位用户的提交次数限制,每10s一次。

后端与Runner通过消息队列进行请求和通信。

评测请求

flowchart LR
A@{shape: circle, label: "Server"}
B@{shape: subprocess, label: "Queue"}
C@{shape: circle, label: "Runner0"}
D@{shape: circle, label: "Runner1"}
A--->B
B--->C
B--->D
B--->...
Loading

评测结果返回

flowchart LR
A@{shape: circle, label: "RunnerX"}
B@{shape: subprocess, label: "Queue"}
C@{shape: circle, label: "Server"}
A--->B
B--->C
Loading

接口文档

统一接口前缀:/api/v1

HTTP普通

1. 用户登录接口

📍 URL

POST /user/login

🔧 请求参数

参数名 类型 是否必填 说明
username String 用户名
password String 用户密码

返回参数ResultVO<String>

字段 类型 说明
code int 状态码,200成功
msg String? 错误信息
data String 用户的token

📌 示例

请求

{
  "username": "root",
  "password": "root"
}

响应

{
  "code": 200,
  "msg": null,
  "data": "xxxxxxxxx"
}
{
  "code": 401,
  "msg": "用户名或密码错误",
  "data": null
}

2. 获取全部题目简要信息

📍 URL

GET /problem

🔧 请求参数

返回参数ResultVO<List<SimpleProblemVO>>

📌 示例

{
  "code": 200,
  "msg": null,
  "data": [
    {
      "uuid": "xxxx-xxxx-xxxx-xxxx",
      "title": "两数之和"
    }
  ]
}

3. 获取单个题目详细信息

📍 URL

GET /problem/{uuid}

🔧 路径参数

参数名 类型 是否必填 说明
uuid String 题目 ID

返回参数ResultVO<ProblemVO>

示例

{
  "code": 200,
  "msg": null,
  "data": {
    "uuid": "xxxx-xxxx-xxxx-xxxx",
    "title": "两数之和",
    "description": "...",
    "example_stdio": [
      ["1 1", "2", ""]
    ],
    "time_limit": 1,
    "memory_limit": 256000
  }
}

4. 提交代码

📍 URL

POST /problem/{uuid}

🔧 请求参数

参数名 类型 是否必填 说明
uuid String 题目 ID
lang String 语言
code String 提交的代码

返回参数ResultVO<String>

示例

{
  "code": 200,
  "msg": null,
  "data": "提交代码成功"
}

如果10s内提交过代码,拒绝评测

{
  "code": 403,
  "msg": "提交过于频繁,稍后重试",
  "data": null
}

5. 获取用户信息

📍 URL

GET /user

🔧 请求参数

返回参数ResultVO<RetUserVO>

示例

{
  "code": 200,
  "msg": null,
  "data": {
    "username": "admin",
    "email": "admin@example.com",
    "nickname": "ding"
    "role": "admin"
  }
}

6. 修改用户信息

📍 URL

POST /user/updateUser

🔧 请求体

参数名 类型 是否必填 说明
username String 用户名
email String 邮箱
nickname String 昵称

示例

{
  "username": "admin",
  "email": "admin@example.com",
  "nickname": "zheng"
}

返回参数ResultVO<String>

{
  "code": 200,
  "msg": null,
  "data": "更新信息成功"
}

7. 修改用户密码

📍 URL

POST /user/password

🔧 请求体

参数名 类型 是否必填 说明
oldPassword String 旧密码
newPassword String 新密码

示例

{
  "oldPassword": "114514",
  "newPassword": "1919810",
}

返回参数ResultVO<String>

{
  "code": 200,
  "msg": null,
  "data": "密码修改成功"
}
{
  "code": 401,
  "msg": "旧密码不正确",
  "data": null
}

8. 查询单个评测记录

📍 URL

GET /problem/submit/{submitId}

返回参数

{
  "code": 200,
  "msg": null,
  "data": {
    "lang": "C++",
    "code": "int main() {}",
    "time": 1919,
    "memory": 1145141,
    "result": "答案正确",
    "exitCode": 0,
    "dateTime": "2025-05-25 22:52:49.031323",
    "score": 100
  }
}

对于正在评测的记录

{
  "code": 200,
  "msg": null,
  "data": {
    "lang": "C++",
    "code": "int main() {}",
    "memory": null,
    "time": null,
    "result": "正在评测",
    "exitCode": null,
    "dateTime": "2025-05-25 22:52:49.031323",
    "score": null
  }
}

对于不存在的记录,返回code 404(Not Found)

{
  "code": 404,
  "msg": "评测记录不存在",
  "data": null
}

9.查询当前用户所有简略评测记录

URL

GET /problem/submit

返回参数

{
  "code": 200,
  "msg": null,
  "data": [
    {
      "submitId": "xxxx-xxxx-xxxx-xxxx",
      "lang": "C++",
      "time": null,
      "memory": null,
      "result": "正在评测",
      "exitCode": 0,
      "submissionTime": "2025-05-25 22:52:49.031323",
      "score": null
    },
    {
      "submitId": "xxxx-xxxx-xxxx-xxxx",
      "lang": "Python",
      "time": 114,
      "memory": 244000,
      "result": "答案正确",
      "submissionTime": "2025-05-24 22:52:49.031323",
      "score": 100
    }
  ]
}

如果发现数组中有正在评测的记录,1s后重新发送请求。

HTTP管理

统一接口前缀:/mgr

1. 创建用户

🎈 URL

POST /user/create

🔨请求参数

参数名 类型 是否必填 说明
username String 用户名
password String 密码
email String 邮箱
nickname String 昵称

返回参数

{
  "code": 200,
  "msg": null,
  "data": "创建用户成功"
}
{
  "code": 409,
  "msg": "用户名已存在",
  "data": null
}

2. 删除用户

URL

DELETE /user/{username}

返回参数

{
  "code": 200,
  "msg": null,
  "data": "删除用户成功"
}
{
  "code": 403,
  "msg": "权限不足",
  "data": null,
}
{
  "code": 404,
  "msg": "用户不存在",
  "data": null
}

3. 创建题目

URL

POST /problem/create

请求参数

参数名 类型 是否必填 说明
title String 标题
description String 描述
time_limit Int 时间限制
time_reserved Int 时间保留限制
memory_limit Int 内存限制
memory_reserved Int 内存保留限制
large_stack Boolean 是否开大栈
output_limit Int 输出行数限制(0为无限制)
process_limit Int 进程限制(0为无限制)
example_stdio List<Tuple<String, String, String>> 样例标准输入,输出,错误输出
stdio List<Tuple<String, String, String>> 测试点标准输入,输出,错误输出

返回参数

{
  "code": 200,
  "msg": null,
  "data": "题目创建成功"
}

4. 删除题目

URL

DELETE /problem/{problemId}

返回参数

{
  "code": 200,
  "msg": null,
  "data": "题目删除成功"
}
{
  "code": 404,
  "msg": "题目不存在",
  "data": null
}

5. 修改题目

URL

PUT /problem

请求参数

参数名 类型 是否必填 说明
problemId String 题目编号
title String 标题
description String 描述
time_limit Int 时间限制
time_reserved Int 时间保留限制
memory_limit Int 内存限制
memory_reserved Int 内存保留限制
large_stack Boolean 是否开大栈
output_limit Int 输出行数限制(0为无限制)
process_limit Int 进程限制(0为无限制)
example_stdio List<Tuple<String, String, String>> 样例标准输入,输出,错误输出
stdio List<Tuple<String, String, String>> 测试点标准输入,输出,错误输出

返回参数

{
  "code": 200,
  "msg": null,
  "data": "修改题目成功"
}
{
  "code": 404,
  "msg": "题目不存在",
  "data": null
}

6. 获取单个题目详细信息

管理员也可使用HTTP普通接口,因此可以通过获取题目简要信息列表来获得所有题目的problemId

URL

GET /problem/{problemId}

返回参数

{
  "code": 200,
  "msg": null,
  "data": {
    "title": "两数之和",
    "description": "给定两个整数,输出它们的和",
    "time_limit": 1,
    "time_reserved": 1,
    "memory_limit": 256000,
    "memory_reserved": 256000,
    "large_stack": false,
    "output_limit": 0,
    "process_limit": 0,
    "example_stdio": [
      ["1 1", "2", ""]
    ],
    "stdio": [
      ["114 514", "1919", ""]
    ]
  }
}
{
  "code": 404,
  "msg": "题目不存在",
  "data": null
}

消息队列RabbitMQ

使用两个Stream,名称分别为Server2RunnerRunner2Server

Server2Runner

生产者Producer

示例:两数之和

commands:
- command: sh
  args:
  - -c
  - |-
    echo '#include <iostream>
    using namespace std;
    int main() {
        int a, b;
        cin >> a >> b;
        cout << a << " + " << b << " = " << a + b << endl;
    }' > main.cpp
  input: ''
  config:
    time_limit: 1
    time_reserved: 1
    memory_limit: 256000
    memory_reserved: 4096000
    large_stack: false
    output_limit: 0
    process_limit: 0
- command: g++
  args:
  - main.cpp
  - -o
  - main
  input: ''
  config:
    time_limit: 1
    time_reserved: 1
    memory_limit: 256000
    memory_reserved: 4096000
    large_stack: false
    output_limit: 0
    process_limit: 0
- command: ./main
  args: []
  input: 1 2
  config:
    time_limit: 1
    time_reserved: 1
    memory_limit: 256000
    memory_reserved: 4096000
    large_stack: false
    output_limit: 0
    process_limit: 0
image: gcc:14.2
submit_id: '......'

Runner2Server

生产者Producer

示例:两数之和

sandbox_results:
- state: Success
  stdout: ''
  stderr: ''
  time: 0
  memory: 1796
- state: Success
  stdout: ''
  stderr: ''
  time: 120
  memory: 73572
- state: Success
  stdout: |
    1 + 2 = 3
  stderr: ''
  time: 0
  memory: 3032
submit_id: '......'

🚨 错误码说明

code 含义
200 成功
204 正在处理
401 未认证 / 登录失效
403 用户权限不足
404 找不到资源
409 Conflict资源冲突
500 服务器内部错误

About

南京大学《软件工程与计算2》期末大项目——Supercode超级码力

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages