⭐这是一个基于 Vue3+Spring Boot+ Spring Cloud 微服务+ Docker 的 编程题目在线评测系统(简称 元仔OJ)

  • 在系统前台,管理员可以创建、管理题目;用户可以自由搜索题目、阅读题目、编写并提交代码。

  • 在系统后端,能够根据管理员设定的题目测试用例在 代码Java(或Python、CPP,功能待实现)沙箱中对代码进行编译、运行、判断输出是否正确。

  • 其中,代码沙箱可以作为独立服务,提供给其他开发者使用。

一、系统展示

1. 前置准备

  • 第一步是准备好数据库哦,代码给在下面了:

CREATE DATABASE IF NOT EXISTS judgeoj DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE judgeoj;
create table question
(
    id          bigint auto_increment comment 'id'
        primary key,
    title       varchar(512)                       null comment '标题',
    content     text                               null comment '内容',
    tags        varchar(1024)                      null comment '标签列表(json 数组)',
    answer      text                               null comment '题目答案',
    submitNum   int      default 0                 not null comment '题目提交数',
    acceptedNum int      default 0                 not null comment '题目通过数',
    judgeCase   text                               null comment '判题用例(json 数组)',
    judgeConfig text                               null comment '判题配置(json 对象)',
    thumbNum    int      default 0                 not null comment '点赞数',
    favourNum   int      default 0                 not null comment '收藏数',
    userId      bigint                             not null comment '创建用户 id',
    createTime  datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime  datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete    tinyint  default 0                 not null comment '是否删除'
)
    comment '题目' collate = utf8mb4_unicode_ci;
​
create index idx_userId
    on question (userId);
​
create table question_submit
(
    id         bigint auto_increment comment 'id'
        primary key,
    language   varchar(128)                       not null comment '编程语言',
    code       text                               not null comment '用户代码',
    judgeInfo  text                               null comment '判题信息(json 对象)',
    status     int      default 0                 not null comment '判题状态(0 - 待判题、1 - 判题中、2 - 成功、3 - 失败)',
    questionId bigint                             not null comment '题目 id',
    userId     bigint                             not null comment '创建用户 id',
    createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete   tinyint  default 0                 not null comment '是否删除'
)
    comment '题目提交';
​
create index idx_questionId
    on question_submit (questionId);
​
create index idx_userId
    on question_submit (userId);
​
create table user
(
    id           bigint auto_increment comment 'id'
        primary key,
    userAccount  varchar(256)                           not null comment '账号',
    userPassword varchar(512)                           not null comment '密码',
    unionId      varchar(256)                           null comment '微信开放平台id',
    mpOpenId     varchar(256)                           null comment '公众号openId',
    userName     varchar(256)                           null comment '用户昵称',
    userAvatar   varchar(1024)                          null comment '用户头像',
    userProfile  varchar(512)                           null comment '用户简介',
    userRole     varchar(256) default 'user'            not null comment '用户角色:user/admin/ban',
    createTime   datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime   datetime     default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete     tinyint      default 0                 not null comment '是否删除'
)
    comment '用户' collate = utf8mb4_unicode_ci;
​
create index idx_unionId
    on user (unionId);
  • 启动redis和nacos,具体操作不列出了,元仔是这样做的:

    启动redis,在redis安装目录下双击运行:

    image-20250530160118408

    启动nacos,进入nacos安装目录/bin,进入cmd执行该命令:

    startup.cmd -m standalone
  • 接着启动代码沙箱,因为没钱买云服务器,只能在虚拟机中实现,下面是远程开发界面的截图:

    image-20250530160140719

    这样就是OK了

  • 接下来启动前端和后端服务

    image-20250530160159691

    image-20250530160220161

    启动完成后就可以访问前端界面(我的是http://localhost:8080/)啦😆

2. 功能展示

  • 这是首页部分,参考北京大学的OJ(http://poj.org/)的界面,简洁明了🫠

    image-20250530160943898

    未登录用户只能浏览题目,使用其他功能会跳转到登录页,比如点击一个题目后面的“Go Go Go,出发咯”就会这样:

    image-20250530161145665

    输入好自定义的账号密码(注意密码至少8位),就可以看见:

    image-20250530163131929

    可见右上角有了登录用户,此时再点击“Go Go Go,出发咯”就可以进入做题界面了:

    image-20250530163249835

    让我们输出答案并提交吧~

    public class Main {
        public static void main(String[] args) {
            int a = Integer.parseInt(args[0]);
            int b = Integer.parseInt(args[1]);
            System.out.println(a + b);
        }
    }

    image-20250530163453650

    此时可以看见代码沙箱处理代码的过程,第一次运行时需要拉取Java的运行镜像,可能会比较慢:

    image-20250530163616498

    我们接着再到前端去看看,点击浏览题目提交:

    image-20250530163735760

    可见我们提交的答案已经成功通过了🥳,真聪明,不是吗?不过为什么内存是0呢,因为代码沙箱的内存检测不太准,所以不用了,只保留了运行时间。

    这只是用户权限能做的事情了,现在看看管理员能做什么🧐

    管理员可以创建题目:

    image-20250530164342767

    image-20250530164401739

    可见题目设置还是非常完善的,除了界面不咋好看😅

    最后就是管理题目了,有没有觉得我们刚刚写的题目太简单,那进入题目管理界面增加难度吧:

    image-20250530164622795

    点击修改:

    image-20250530164643969

    然后我们就可以根据自己的实力修改了呢。

    总共就这些功能了,看起来很单薄诶😥,但是作为一名全干工程师,元仔2个多月做完前后端加上代码沙箱已经燃尽了,主要还是踩得坑太多,要修的🐛太多。等我技术上来了,一定可以做得更好的🤓

    下一章就告诉你我是怎么完成这个项目的。

二、代码实现

施工中...