Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Code-TestX

PHP MySQL Tailwind License PRs Welcome


目录


项目简介

Code-TestX 是一个面向编程学习与算法竞赛的在线评测(OJ)平台。它提供了从题目练习、代码提交、自动评测到竞赛管理的完整闭环,旨在帮助开发者系统性地提升编程能力。

核心理念:让编程学习像游戏闯关一样有趣,让算法竞赛像实战演练一样真实。

项目背景

在当今技术快速发展的时代,编程能力已成为核心竞争力之一。然而,许多学习者在提升编程技能的过程中面临以下痛点:

  • × 缺乏系统性的练习平台
  • × 无法获得即时的代码反馈
  • × 缺少真实的竞赛环境
  • × 学习进度难以追踪

Code-TestX 正是为解决这些问题而生。它不仅仅是一个刷题平台,更是一个集学习、训练、竞赛于一体的综合性编程生态系统。

适用场景

场景 描述
个人学习 按难度梯度刷题,AI 助手实时答疑
高校教学 布置编程作业,自动评测学生代码
竞赛训练 模拟真实竞赛环境,多阶段晋级
企业招聘 技术笔试平台,支持多语言代码考核
社区运营 排行榜激励,消息通知,用户互动

核心特性

编程训练模块

海量题库

  • 多级难度体系:1-7 级难度梯度,从入门到竞赛全覆盖

    • 1⭐ 简单:基础语法练习
    • 2⭐ 中等:数据结构入门
    • 3⭐ 困难:算法思维训练
    • 4⭐ 专家:复杂问题求解
    • 5⭐ 地狱:高难度挑战
    • 6⭐ 特殊:人工评测题(如复杂模拟、开放性题目)
    • 7⭐ 竞赛:仅用于竞赛阶段
  • 题目元数据:标题、描述、输入/输出说明、样例、时间/内存限制

  • 测试数据版本控制:支持 V2 JSON 格式,可热更新测试数据

多语言支持

语言 编译器/解释器 版本要求
C GCC 支持 C11 标准
C++ G++ 支持 C++17 标准
Python CPython 3.8+
Java OpenJDK 11+
PHP PHP 7.4+
JavaScript Node.js 14+

智能代码编辑器

  • 基于 Ace Editor,提供专业级编辑体验
  • 语法高亮、自动补全、代码折叠
  • 字号调节、主题切换(Dracula 暗色主题)
  • 多文件命名(自动匹配语言后缀)

实时评测反馈

提交代码 → 编译检查 → 执行测试 → 逐点校验 → 汇总结果
    ↓          ↓          ↓          ↓          ↓
   <1s       <3s       <5s       <2s       <1s
  • 即时响应:通常在 5-10 秒内完成评测
  • 逐点详情:每个测试点的执行时间、内存消耗、判定结果
  • 错误诊断:编译错误、运行时错误、超时/超内存等详细信息
  • 部分得分:支持子任务部分得分,精确到 0.01 分

学习追踪

  • 自动记录:通过的题目、得分、耗时、内存
  • 统计数据:总通过数、总得分、最高分、擅长难度
  • 难度分布图:可视化展示各难度通过情况
  • 提交历史:完整的提交记录,含代码快照

排行榜

  • 综合评分算法
    总分 = 通过数 × 5 + Σ(难度系数) + 代码质量分
    
    其中难度系数:简单=10,中等=20,困难=35,专家=50,地狱=70
  • 代码质量分:基于内存和时间消耗计算(越低越好)
  • TOP 50 展示:含金银铜牌标识

TOJ-V2 评测引擎

这是 Code-TestX 最核心的模块

多沙箱后端

后端 适用平台 特点
isolate Linux IOI 官方沙箱,最安全,支持 cgroup 内存控制
posix Linux/macOS setrlimit 资源限制,无需额外安装
windows Windows Job 对象 + tasklist 采样监控

引擎会自动探测并选择最优后端,优先级:isolate > posix > windows

V2 测试数据格式

{
  "version": 2,
  "defaults": {
    "time_limit_ms": 2000,
    "memory_limit_kb": 262144,
    "output_limit_kb": 8192,
    "checker": { "type": "token" }
  },
  "policy": {
    "scoring": "partial",
    "reveal": "summary",
    "stop_on_first_failure": false,
    "include_sample": true
  },
  "groups": [
    {
      "id": "subtask1",
      "name": "小数据",
      "points": 30,
      "mode": "sum",
      "depends_on": []
    }
  ],
  "cases": [
    {
      "id": "case-1",
      "group": "subtask1",
      "points": 10,
      "in": "1 2",
      "out": "3",
      "visibility": "public"
    }
  ]
}

校验器类型

类型 描述 适用场景
exact 逐字节精确比较 严格输出匹配
trim 去除首尾空白后比较 忽略多余空行
token 按空白符分词比较(默认) 大多数题目
lines 逐行比较 多行输出
unordered_lines 行集合比较(忽略顺序) 输出行顺序无关
float 浮点数比较(绝对/相对误差) 数值计算题
range 输出值在指定范围内 范围校验题
regex 正则表达式匹配整段输出 格式校验
fields 按列(字段)分别校验 表格输出
script 特殊判题脚本(Python/Node/PHP) 复杂逻辑校验

静态安全检查

自动检测并拦截以下危险模式:

语言 拦截项
PHP exec, shell_exec, system, eval, assert, curl_exec, fsockopen, file_put_contents, mysqli_connect
Python os.system, subprocess, eval, exec, __import__, socket, open, shutil
JavaScript require('child_process'), fetch, fs.unlink, eval, new Function
C/C++ system, popen, fork, socket, ptrace, asm, dlopen
Java Runtime.getRuntime(), ProcessBuilder, Class.forName, System.exit

竞赛系统

多阶段竞赛

  • 支持无限阶段(海选 → 初赛 → 复赛 → 决赛)
  • 每阶段独立时间窗口
  • 阶段状态:预备 → 报名中 → 进行中 → 已结束

动态出题机制

  • 报名时从竞赛题库(难度 7)随机分配 2-3 题
  • 每位参赛者题目组合不同
  • 任务进度实时追踪(JSON 存储 fptm 字段)

晋级机制

  • 完成当前阶段所有任务 → 自动晋级
  • 上一阶段未通过 → 无法报名下一阶段
  • 管理员可手动调整选手状态

竞赛报名管理

  • 报名列表(含状态:待审核/已通过/已淘汰)
  • 支持选手退赛(同时清理阶段报名记录)

AI 智能助手

基于天工 AI API 构建的编程问答助手:

  • 技术特性

    • Server-Sent Events (SSE) 流式响应
    • 支持 Markdown 渲染(含代码高亮)
    • 支持 LaTeX 数学公式(KaTeX 渲染)
    • 智能推荐相关问题(suggestion)
  • 配置方式: 管理员后台配置 SecretID/SecretKey

消息通知系统

类型 描述 发送方式
全体公告 发送给所有用户 user_for = '0'
个人消息 发送给指定用户 user_for = '用户ID|用户ID'
系统通知 评测结果通知 自动触发

管理后台

题目管理

  • CRUD 操作:创建、查看、修改、删除
  • 批量导入:支持 JSON Array / JSONL / CSV / Markdown 表格四种格式
  • 测试数据编辑器:可视化编辑 V2 JSON 测试数据
  • 字段说明
    • dv:输出范围校验(如 -2>9
    • dvx:按元素范围校验(如 [-3>9,-1>7]

人工评测

  • 特殊题(难度 6)代码人工审核
  • 操作:通过(自动记录通过状态)或 不通过(删除记录)
  • 结果通过消息中心通知用户

竞赛管理

  • 竞赛 CRUD(标题、描述、分类、时间、状态)
  • 阶段管理(名称、描述、序号、时间、状态)
  • 报名列表查看与删除

公告管理

  • 支持 Select2 多选用户
  • 支持全体用户或指定用户发送

技术栈

后端

组件 技术 说明
语言 PHP 7.4+ 原生开发,无框架依赖
数据库 MySQL 5.7+ InnoDB/MyISAM 混合引擎
沙箱 isolate / POSIX / Windows 三后端自适应
安全 静态代码扫描 + CSRF Token 双重防护
缓存 可通过文件缓存扩展

前端

组件 技术 说明
样式 Tailwind CSS 3.4 原子化 CSS 框架
交互 原生 JavaScript 无框架依赖
编辑器 Ace Editor 专业代码编辑器
图表 Chart.js 统计可视化
Markdown marked.js + KaTeX 富文本渲染
UI 组件 LayUI (弹窗/表单) 轻量级 UI 库
图标 Font Awesome 4.7 图标库

系统架构

整体架构图

┌─────────────────────────────────────────────────────────────────────────────┐
│                            用户端 (Frontend)                               │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ 题库浏览  │ │ 代码提交  │ │ 竞赛报名  │ │ 排行榜   │ │ AI助手   │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐                    │
│  │ 消息中心  │ │ 刷题记录  │ │ 个人中心  │ │ 竞赛详情  │                    │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘                    │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          HTTP API 层 (Endpoint)                           │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  code-runner.php   │  code-runnerx.php   │  code-check.php     │      │
│  │  (普通评测)         │  (竞赛评测)          │  (人工评测申请)      │      │
│  └─────────────────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         TOJ-V2 评测引擎 (Engine)                          │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │                    Judge.php (评测主流程)                       │      │
│  │  编译 → 加载测试套件 → 调度执行 → 结果汇总                       │      │
│  └─────────────────────────────────────────────────────────────────┘      │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐       │
│  │  TestSuite  │ │   Checker   │ │   Sandbox   │ │   Guard     │       │
│  │ (测试加载)   │ │ (答案校验)   │ │ (沙箱后端)   │ │ (安全检查)   │       │
│  └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘       │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                       │
│  │  Language   │ │  RangeExpr  │ │ SpecialJudge│                       │
│  │ (语言支持)   │ │ (范围解析)   │ │ (特殊判题)   │                       │
│  └─────────────┘ └─────────────┘ └─────────────┘                       │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         数据层 (Repository + MySQL)                       │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  user  │ coding_problems  │ code_submissions  │ code_person    │      │
│  │  (用户) │ (题目)           │ (提交记录)         │ (人工评测队列)   │      │
│  ├─────────────────────────────────────────────────────────────────┤      │
│  │  problem_pass_users  │ competitions  │ competition_stages      │      │
│  │  (通过记录)           │ (竞赛)        │ (竞赛阶段)               │      │
│  ├─────────────────────────────────────────────────────────────────┤      │
│  │  competition_registrations │ stage_registrations  │ site_mail  │      │
│  │  (竞赛报名)                  │ (阶段报名)            │ (消息)     │      │
│  └─────────────────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────────────────┘

评测执行流程

┌─────────────────────────────────────────────────────────────────────────────┐
│                           代码提交请求                                      │
│                    POST /run/code-runner.php                              │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    Endpoint::handleJudge()                                │
│  ├── 验证 Token (CSRF 防护)                                               │
│  ├── 解析请求参数 (code, language, problem_id, user_id)                   │
│  ├── 代码长度限制检查 (默认 256KB)                                        │
│  └── 语言可用性检查                                                       │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    Repository 层                                           │
│  ├── findProblem() - 查询题目信息                                         │
│  ├── checkRateLimit() - 限流检查 (用户/IP/题目间隔)                       │
│  └── createSubmission() - 创建提交记录 (状态: PENDING)                    │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    Guard::inspect() - 静态安全检查                         │
│  ├── 去除注释和字符串字面量                                               │
│  ├── 匹配危险函数模式 (exec/eval/system/等)                               │
│  └── 根据策略 (off/warn/block) 决定是否阻断                               │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    Judge::run() - 评测主流程                              │
│                                                                           │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  1. 编译阶段 (Language::compile / syntax_check)                │      │
│  │     ├── 写入源文件到工作目录                                     │      │
│  │     ├── 沙箱执行编译命令 (isolate/posix)                        │      │
│  │     └── 检查编译产物与错误信息                                   │      │
│  └─────────────────────────────────────────────────────────────────┘      │
│                                    │                                      │
│                                    ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  2. 加载测试套件 (TestSuite::load)                             │      │
│  │     ├── 解析 V2 JSON 测试数据                                   │      │
│  │     ├── 构建 groups 依赖关系                                    │      │
│  │     ├── 分配分值 (自动归一化到 100 分)                          │      │
│  │     └── 加载外置测试数据文件 (.in/.out/.gz)                     │      │
│  └─────────────────────────────────────────────────────────────────┘      │
│                                    │                                      │
│                                    ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  3. 测试点调度执行 (runAllCases)                               │      │
│  │     ├── 按分组依赖关系排序                                      │      │
│  │     ├── 并行/串行执行 (受 max_parallel 控制)                   │      │
│  │     ├── 首错即停 (stop_on_first_failure)                       │      │
│  │     └── TLE 重测 (recheck_tle_serially)                        │      │
│  └─────────────────────────────────────────────────────────────────┘      │
│                                    │                                      │
│                                    ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  4. 单测试点执行 (runBatch)                                    │      │
│  │     ├── 准备输入文件 (stdin)                                    │      │
│  │     ├── 沙箱运行用户程序                                        │      │
│  │     ├── 监控资源 (time/memory/output)                          │      │
│  │     ├── 读取输出文件 (stdout/stderr)                           │      │
│  │     └── Checker::check() 校验答案                              │      │
│  └─────────────────────────────────────────────────────────────────┘      │
│                                    │                                      │
│                                    ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────┐      │
│  │  5. 结果汇总 (report)                                          │      │
│  │     ├── 计算总得分 (支持 partial/binary)                       │      │
│  │     ├── 统计通过数/总测试点                                     │      │
│  │     ├── 记录峰值时间/内存                                       │      │
│  │     └── 生成逐测试点详情                                        │      │
│  └─────────────────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    Repository::finishSubmission()                         │
│  ├── 更新 code_submissions 表 (verdict, score, passed_cases, etc.)       │
│  └── 如果 AC → markPassed() 更新 problem_pass_users 和题目通过数          │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                    返回 JSON 结果给前端                                   │
│  {                                                                        │
│    "success": true,                                                       │
│    "verdict": "AC",                                                       │
│    "score": 100.00,                                                       │
│    "results": [...]                                                       │
│  }                                                                        │
└─────────────────────────────────────────────────────────────────────────────┘

快速开始

环境要求

组件 版本 说明
PHP 7.4+ 需启用 mysqlijsongdmbstring 扩展
MySQL 5.7+ 支持 InnoDB 外键约束
Web Server Nginx / Apache 需支持 URL 重写
isolate (可选) 最新 Linux 下推荐安装,提供最高安全级别

安装步骤

1.访问站点/install/目录(安装完一定要记得删除这个目录) 2.见下

# 1. 克隆仓库
git clone https://github.com/xhgzs1314/code-testx.git
cd code-testx

# 2. 导入数据库
mysql -u root -p < inl.sql

# 3. 配置数据库连接
cp config.example.php config.php
vim config.php
# 填写以下配置:
#   $db_host = 'localhost';
#   $db_user = 'your_username';
#   $db_pass = 'your_password';
#   $db_name = 'code_testx';

# 4. 设置目录权限
chmod -R 755 data/
chmod -R 755 tmp/
chmod -R 755 run/

# 5. (可选) 配置 isolate 沙箱
apt-get install libcap-dev
git clone https://github.com/ioi/isolate.git
cd isolate && make && make install

# 6. 配置 Web 服务器 (见下方)

默认账号

角色 用户名 密码 说明
普通用户 user 123456 可刷题、竞赛、查看排行榜
管理员 admin 123456 后台管理入口
系统账号 u_n6Tehu 随机生成 示例用户(可删除)

部署指南

Nginx 配置

server {
    listen 80;
    server_name code-testx.yourdomain.com;
    root /var/www/code-testx;
    index index.php;

    # 主入口
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP 处理
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # 禁止访问敏感文件
    location ~ /\. {
        deny all;
    }
    location ~ (config\.php|inl\.sql|\.md|\.yml) {
        deny all;
    }

    # 评测引擎入口 (必须可访问)
    location /run/ {
        try_files $uri $uri/ /run/code-runner.php?$query_string;
    }
}

Apache 配置 (.htaccess)

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    # 主入口
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [QSA,L]
    
    # 禁止访问敏感文件
    <FilesMatch "^(config\.php|inl\.sql|\.md|\.yml)$">
        Order Deny,Allow
        Deny from all
    </FilesMatch>
</IfModule>

沙箱配置

Linux (isolate 推荐)

# 检查 isolate 是否可用
isolate --version

# 如果安装成功,引擎会自动检测并使用
# 默认 box_id 为 0,可多实例并行

Linux (POSIX 模式)

系统默认使用 POSIX 后端,通过 setrlimit 限制资源。无需额外配置,但安全性低于 isolate。

Windows 模式

使用 Windows Job 对象 + tasklist 采样监控。适用于开发环境或 Windows 服务器。

性能优化建议

  1. PHP OPcache:启用 OPcache 加速

    opcache.enable=1
    opcache.memory_consumption=128
    opcache.max_accelerated_files=4000
  2. MySQL 优化

    • code_submissions 表添加索引(已在 inl.sql 中定义)
    • 定期清理过期的提交记录
  3. 并发评测

    • 调整 max_parallel 参数(默认自动检测 CPU 核心数)
    • 确保沙箱后端支持并行(isolate 支持多 box_id)
  4. CDN 加速

    • 静态资源可使用 CDN 加速
    • 修改 ast/ 目录下的资源引用

API 文档

通用规范

  • 请求方式POST
  • Content-Typeapplication/json
  • 响应格式application/json

错误码

HTTP 状态码 含义
200 成功(含编译错误)
400 请求参数错误
401 Token 无效
404 题目不存在
413 代码长度超限
429 提交频率过快
500 服务器内部错误
503 服务不可用

1. 代码提交 (普通模式)

端点POST /run/code-runner.php

请求体

{
    "code": "#include <iostream>\nusing namespace std;\n\nint main() {\n    int a, b;\n    cin >> a >> b;\n    cout << a + b << endl;\n    return 0;\n}",
    "language": "cpp",
    "problem_id": 1001,
    "user_id": "u_n6Tehu",
    "token": "xxxxx"
}

响应(成功)

{
    "success": true,
    "all_passed": true,
    "verdict": "AC",
    "verdict_label": "通过",
    "score": 100.00,
    "scoring": "partial",
    "passed_cases": 4,
    "total_cases": 4,
    "max_time_ms": 600,
    "max_memory_kb": 10104,
    "time_limit_ms": 1000,
    "memory_limit_kb": 262144,
    "compile": {
        "ok": true,
        "message": "",
        "time_ms": 150.5
    },
    "results": [
        {
            "case": 1,
            "passed": true,
            "accuracy": "100.00%",
            "verdict": "AC",
            "verdict_label": "通过",
            "time_ms": 235.08,
            "memory_kb": 9628,
            "points": 20,
            "earned": 20
        }
    ],
    "groups": [
        {
            "id": "sample",
            "name": "样例",
            "mode": "sum",
            "points": 20,
            "earned": 20,
            "passed": 1,
            "total": 1
        }
    ],
    "language": "cpp",
    "judge_backend": "isolate"
}

响应(编译错误)

{
    "success": false,
    "error": "编译错误:\nmain.cpp: In function 'int main()':\nmain.cpp:5:5: error: 'cout' was not declared in this scope",
    "verdict": "CE",
    "compile": {
        "ok": false,
        "message": "..."
    }
}

2. 代码提交 (竞赛模式)

端点POST /run/code-runnerx.php

请求体与普通模式相同。通过后会自动标记阶段任务完成。

响应

{
    "success": true,
    "all_passed": true,
    "verdict": "AC",
    "stage_updated": true,
    // ... 其他字段同 code-runner.php
}

3. 人工评测申请

端点POST /run/code-check.php

请求体

{
    "code": "def solve():\n    pass",
    "language": "python",
    "problem_id": 6001,
    "user_id": "u_n6Tehu",
    "token": "xxxxx"
}

响应(成功)

{
    "success": true,
    "message": "提交成功,请等待人工评审"
}

响应(重复提交)

{
    "success": false,
    "error": "你已经提交过答案了",
    "status": 409
}

4. 限流响应

当触发限流时,返回 429 Too Many Requests

{
    "success": false,
    "error": "同一题目的提交间隔需大于 5 秒",
    "retry_after": 3
}

数据库设计

ER 图 (核心表)

┌─────────────────┐     ┌─────────────────────┐     ┌──────────────────┐
│      user       │     │  coding_problems    │     │ code_submissions │
├─────────────────┤     ├─────────────────────┤     ├──────────────────┤
│ id (PK)         │────▶│ id (PK)             │◀────│ problem_id (FK)  │
│ username        │     │ title               │     │ user_id (FK)     │
│ password        │     │ description         │     │ code             │
│ uname           │     │ difficulty          │     │ language         │
│ bdmail          │     │ solution_count      │     │ verdict          │
└─────────────────┘     │ test_cases (JSON)   │     │ score            │
        │               │ time_limit_ms       │     │ passed_cases     │
        │               │ memory_limit_kb     │     │ max_time_ms      │
        │               └─────────────────────┘     │ max_memory_kb    │
        │                       │                   │ created_at       │
        │                       │                   └──────────────────┘
        │                       │                            │
        ▼                       ▼                            ▼
┌─────────────────┐     ┌─────────────────────┐     ┌──────────────────┐
│problem_pass_users│     │  competition        │     │  code_person     │
├─────────────────┤     ├─────────────────────┤     ├──────────────────┤
│ id (PK)         │     │ id (PK)             │     │ id (PK)          │
│ problem_id (FK) │     │ title               │     │ wtm (problem_id) │
│ user_id (FK)    │     │ description         │     │ userid           │
│ pass_time       │     │ overall_start_time  │     │ codes            │
│ ram             │     │ overall_end_time    │     │ status           │
│ utime           │     │ status              │     │ score            │
│ language        │     └─────────────────────┘     └──────────────────┘
│ best_score      │              │
└─────────────────┘              │
                                 ▼
                        ┌─────────────────────┐
                        │ competition_stages  │
                        ├─────────────────────┤
                        │ id (PK)             │
                        │ competition_id (FK) │
                        │ name                │
                        │ order_num           │
                        │ start_time          │
                        │ end_time            │
                        │ status              │
                        └─────────────────────┘
                                 │
                                 ▼
                        ┌─────────────────────┐
                        │stage_registrations  │
                        ├─────────────────────┤
                        │ id (PK)             │
                        │ stage_id (FK)       │
                        │ user_id             │
                        │ status              │
                        │ fptm (JSON)         │ ← 任务分配数据
                        └─────────────────────┘

表结构说明

表名 引擎 说明
user InnoDB 用户表,存储账号密码和基本信息
coding_problems InnoDB 题目主表,含 V2 JSON 测试数据
code_submissions InnoDB 提交记录表,含评测结果详情
code_person MyISAM 人工评测队列(特殊题)
problem_pass_users InnoDB 通过记录表,用于排行榜计算
competitions MyISAM 竞赛主表
competition_stages MyISAM 竞赛阶段表
competition_registrations MyISAM 竞赛报名表
stage_registrations MyISAM 阶段报名表,含 fptm 任务分配
site_mail MyISAM 消息表(公告和个人消息)

目录结构

code-testx/
├── engine/                           # TOJ-V2 评测引擎核心
│   ├── bootstrap.php                 # 引擎装载器
│   ├── Config.php                    # 全局配置管理
│   ├── Verdict.php                   # 评测结果常量 + 异常类
│   ├── Http.php                      # HTTP 请求/响应封装
│   ├── Support.php                   # 基础设施 (平台探测/文件操作)
│   ├── Sandbox.php                   # 沙箱抽象层
│   ├── SandboxIsolate.php            # isolate 沙箱后端
│   ├── SandboxPosix.php              # POSIX setrlimit 后端
│   ├── SandboxWindows.php            # Windows Job 后端
│   ├── Language.php                  # 语言支持注册 (6 种语言)
│   ├── Guard.php                     # 静态代码安全检查
│   ├── RangeExpr.php                 # 数值范围表达式解析
│   ├── Checker.php                   # 答案校验器 (10+ 种)
│   ├── SpecialJudge.php              # 特殊判题脚本执行器
│   ├── TestSuite.php                 # V2 测试数据加载器
│   ├── Judge.php                     # 评测主流程
│   ├── Repository.php                # 数据访问层
│   └── Endpoint.php                  # HTTP 入口控制器
│
├── run/                              # 评测 HTTP 入口
│   ├── code-runner.php               # 普通评测入口 (practice)
│   ├── code-runnerx.php              # 竞赛评测入口 (contest)
│   └── code-check.php                # 人工评测申请入口 (manual)
│
├── users/                            # 用户模块
│   └── login/                        # 登录/注册页面
│       ├── index.php                 # 登录/注册页面 (含验证码)
│       ├── log.php                   # 登录逻辑
│       └── reg.php                   # 注册逻辑
│
├── cofd/                             # 公共依赖库
│   ├── common.php                    # 数据库连接
│   ├── token.php                     # CSRF Token 生成/验证
│   └── locokie.php                   # Cookie 辅助函数
│
├── ast/                              # 前端静态资源
│   ├── 3.4.16.js                     # Tailwind CSS CDN
│   ├── font-awesome/                 # Font Awesome 4.7 图标库
│   ├── layui/                        # LayUI 组件库
│   ├── css/                          # 自定义样式
│   ├── js/                           # 自定义 JS
│   └── photo/                        # 图片资源
│
├── package/                          # NPM 前端库 (本地)
│   ├── ace-builds/                   # Ace 编辑器
│   ├── chart.umd.min.js              # Chart.js 图表
│   ├── marked.min.js                 # Markdown 渲染
│   ├── katex.min.js + .css           # LaTeX 数学渲染
│   ├── auto-render.min.js            # KaTeX 自动渲染
│   ├── mermaid.min.js                # Mermaid 流程图
│   ├── github-markdown.min.css       # GitHub 风格 Markdown
│   ├── sweetalert2/                  # 弹窗组件
│   └── select2.min.js + .css         # 多选下拉框
│
├── admin/                            # 后台管理模块
│   ├── set.php                       # 后台布局 + 侧边栏
│   ├── index.php                     # 后台首页 (引擎文档展示)
│   ├── login.php                     # 后台登录页
│   ├── logout.php                    # 后台登出
│   ├── keylist.php                   # 题库列表 (查看/删除)
│   ├── keyupdate.php                 # 单题修改
│   ├── keypush.php                   # 新建题目 (表单)
│   ├── keypush2.php                  # 批量导入题目 (JSON/JSONL/CSV/Markdown)
│   ├── keyplus.php                   # 人工评测管理
│   ├── compelist.php                 # 竞赛列表管理
│   ├── callgglist2.php               # 阶段管理
│   ├── callgglist3.php               # 阶段报名列表
│   ├── callgglist4.php               # 竞赛报名列表
│   ├── dl.php                        # 公告管理
│   ├── robot_tiangong.php            # AI 密钥配置
│   ├── cdxl.php                      # 个人信息修改
│   ├── gapwp.php                     # 密码修改
│   ├── shop.php                      # 商品管理 (预留)
│   ├── ssearch.php                   # 用户搜索 API (Select2)
│   ├── call/                         # 后台处理脚本
│   │   ├── calldlgg.php              # 添加公告
│   │   ├── calldlgg2.php             # 添加竞赛
│   │   ├── calldlgg3.php             # 添加阶段
│   │   ├── callggdell.php            # 删除公告
│   │   ├── callggdell2.php           # 删除竞赛
│   │   ├── callggdell3.php           # 删除阶段
│   │   ├── callggdell4.php           # 删除阶段报名
│   │   ├── callggdell5.php           # 删除竞赛报名
│   │   ├── callsh.php                # 人工评测审核 (通过/不通过)
│   │   ├── callpost.php              # 修改公告表单
│   │   ├── callpostdel.php           # 删除题目
│   │   ├── callxggglist.php          # 修改公告
│   │   ├── callxggglist2.php         # 修改竞赛
│   │   ├── callxggglist3.php         # 修改阶段
│   │   ├── callyui.php               # 更新公告
│   │   ├── callyui2.php              # 更新竞赛
│   │   ├── callyui3.php              # 更新阶段
│   │   ├── callpass.php              # 修改密码处理
│   │   ├── callbo.php                # 修改个人信息处理
│   │   ├── calllog.php               # 后台登录处理
│   │   ├── newtm.php                 # 新建题目处理 (API)
│   │   └── keyupdate_do.php          # 修改题目处理
│   └── xuplwzxy/                     # 个人信息存储
│       └── xydoc.php                 # 昵称/QQ/签名数据
│
├── competition/                      # 竞赛模块 (子路由)
│   ├── prepare/                      # 竞赛报名处理
│   │   └── index.php                 # 报名逻辑 (含阶段晋级检查)
│   ├── oning/                        # 进入竞赛
│   │   └── index.php                 # 展示任务列表 + 进度
│   └── quit/                         # 退赛处理
│       └── index.php                 # 退赛逻辑
│
├── index.php                         # 用户端主页 (框架页 + 侧边栏)
├── dashboard.php                     # 题库列表 (含筛选/分页/搜索)
├── codereads.php                     # 题目详情 + 代码提交 (Ace 编辑器)
├── competition.php                   # 竞赛报名列表
├── competition_mine.php              # 我的竞赛详情
├── haspassed.php                     # 刷题记录 (含统计图表)
├── submission_history.php            # 单题提交历史
├── submission_detail.php             # 单次提交详情
├── notice.php                        # 消息中心 (全体/个人)
├── phb.php                           # 排行榜
├── airobot.php                       # AI 智能助手 (SSE 流式)
├── set.php                           # 登录拦截 (检查 Cookie)
├── inl.sql                           # 完整数据库结构
├── config.example.php                # 数据库配置示例
├── engine.md                         # 评测引擎文档
└── README.md                         # 项目说明

常见问题

Q1: 评测时提示 "评测机未安装 Python 运行环境"?

A: 检查系统是否安装了对应语言的解释器/编译器:

# Python
python3 --version

# C++
g++ --version

# Java
javac -version
java -version

# Node.js
node --version

# PHP
php --version

Q2: 如何启用 isolate 沙箱?

A:

# 安装 isolate
git clone https://github.com/ioi/isolate.git
cd isolate
make
sudo make install

# 验证
isolate --version

# 引擎会自动检测并使用

Q3: 提交代码后一直显示 PENDING?

A: 检查以下几点:

  1. 数据库连接是否正常
  2. run/ 目录是否有执行权限
  3. PHP 错误日志是否有报错
  4. 检查 code_submissions 表是否有新记录

Q4: 如何批量导入题目?

A: 使用后台的 keypush2.php 页面,支持四种格式:

  • JSON Array[{...}, {...}]
  • JSONL:每行一个 JSON 对象
  • CSV:第一行为表头
  • Markdown 表格:标准 Markdown 表格格式

Q5: 如何配置 AI 智能助手?

A:

  1. 登录后台 (/admin/login.php)
  2. 进入「智能助手-天工AI」
  3. 填写 SecretID 和 SecretKey
  4. 保存配置

Q6: 特殊题(难度 6)如何评测?

A: 特殊题需要人工评测:

  1. 用户在题目页点击「申请人工评测」
  2. 代码进入 code_person 队列
  3. 管理员在后台 keyplus.php 查看
  4. 点击「通过」或「不通过」
  5. 结果通过消息中心通知用户

Q7: 如何自定义限流规则?

A: 编辑 engine/judge.config.php(如不存在则创建):

<?php
return [
    'rate_limit' => [
        'enabled' => true,
        'per_user_window_s' => 60,      // 60 秒窗口
        'per_user_max' => 8,            // 最多 8 次
        'per_problem_min_gap_s' => 5,   // 同题间隔 5 秒
        'per_ip_window_s' => 60,
        'per_ip_max' => 30,
    ],
];

Q8: 支持哪些 PHP 扩展?

A: 必需的扩展:

  • mysqli - 数据库连接
  • json - JSON 解析
  • gd - 验证码生成
  • mbstring - 多字节字符串处理

报告 Bug

请使用 GitHub Issues 报告 Bug,并包含:

  1. 环境信息:PHP 版本、MySQL 版本、操作系统
  2. 复现步骤:详细的操作步骤
  3. 期望行为:你期望发生什么
  4. 实际行为:实际发生了什么
  5. 日志/截图:相关的错误日志或截图

功能建议

如果你有好的想法,欢迎提交 Issue 或 Pull Request。建议包含:

  1. 功能描述:这个功能是做什么的
  2. 使用场景:在什么情况下会用到
  3. 实现思路:你建议如何实现

许可证

本项目采用 MIT License 开源许可证。


鸣谢

开源项目

项目
IOI isolate
Ace Editor
Tailwind CSS
Chart.js
marked.js
KaTeX
LayUI
Font Awesome

About

Code-TestX - 一个在线编程评测(OJ)平台,支持多语言代码提交、自动评测、竞赛管理和AI智能助手。采用 PHP + MySQL + Tailwind CSS 构建,内置 TOJ-V2 评测引擎,支持 isolate/POSIX/Windows 三沙箱后端

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages