一句话定位:一套「Java 后端 + Vue2 管理端/学生端 + 微信原生小程序」的完整考试系统,2019 年开源至今仍在维护,装机量很大、部署确实简单;代价是技术栈停在 Spring Boot 2.1 + Vue2,协议是 AGPL-3.0,数据库脚本还得去官网领。
项值
仓库地址https://gitee.com/mindskip/xzs-mysql (PostgreSQL 版:gitee.com/mindskip/uexam)
项目定位前后端分离的在线考试系统,含管理端、学生端 Web 与微信小程序
官网 / 演示https://www.mindskip.net ;学生端演示 :7001,教师端 :7002
开源协议AGPL-3.0(LICENSE、pom.xml、Gitee 项目信息三处一致)
后端技术栈Spring Boot 2.1.6.RELEASE / Java 8 / MyBatis 2.1 / Spring Security / Undertow / MySQL 8
前端技术栈Vue 2.7.16 + Element UI 2.15 + vue-cli 4.5 + Vuex 3 + axios;小程序为微信原生
当前版本3.9.0(pom.xml、两个前端 package.json、release/xzs-3.9.0.jar 一致)
社区热度Gitee 19,275 Star / 3,003 Fork / 1,420 Watch(2026-11-10 查询)
维护方武汉思维跳跃科技有限公司(mindskip),仓库创建于 2019-09-07,最近提交 2026-11-10
部署形态集成部署(前端打进 jar)/ 前后端分离 / docker-compose
文档日期2026-11-10

1. 项目是什么

它是「题库 → 试卷 → 考试 → 判分 → 错题本」这一整条链路的开源实现,不是只给你一个答题页面。仓库里装着四份东西:一个 Spring Boot 后端、管理端 Vue、学生端 Vue、微信原生小程序,四者共用同一套接口。

用一句话概括业务模型:

概念对应表说明
学科t_subject年级 + 科目,题目挂在学科下
题目t_question + t_text_content题干是富文本 HTML,单独存一张表,支持图片、表格、数学公式
试卷t_exam_paperpaper_type 区分固定试卷、时段试卷、任务试卷
任务t_task_exam管理员按年级下发,每个学生只能做一次
答卷t_exam_paper_answer一次作答的总分、状态、耗时
逐题作答t_exam_paper_question_customer_answer每题对错、得分、你的答案
消息t_message + t_message_user管理员群发,按人记录已读

需要先想清楚的一点:它提供的是「系统」,不是「题库」。仓库里的 sql/xzs-mysql.sql 只有 13 张表的结构加两条用户记录,没有学科、题目、试卷数据,README 也写明完整脚本要去官网文档站领。clone 下来跑通之后是一个空系统,第一个学科、第一道题都得自己录。

另外两个容易混淆的点:

  • mindskip/xzs-mysql 是 MySQL 版,mindskip/uexam 是 PostgreSQL 版,功能同源但仓库分开维护,选型前先确认自己用哪个库。
  • 官网同时挂着「维多多培训考试系统」「思多多智能考试系统」两个商业产品,它们和这个开源仓库不是同一个东西,功能对比见第 8 节。

2. 核心特性

特性说明对使用者的价值
三端一套后端管理端、学生 Web、微信小程序都打同一组 /api/** 接口后端只维护一次,小程序和 Web 的题目、成绩天然一致
三种试卷形态固定试卷(组好不变)、时段试卷(限时开放)、任务试卷(按年级下发,限做一次)覆盖练习、模考、作业三种真实场景,不用二次开发
五种题型单选、多选、判断、填空、简答;题干富文本支持图片、表格、公式理科公式题、带图题能直接录,不必接外部题库
答卷完整留痕总分、状态、逐题对错与你的答案全部落库,可回看、可导出学生自助练习闭环完整,老师只需看结果
错题本答错自动进 question-error 页面,关联题目详情这是很多付费系统才做的功能,开源版直接有
单 jar 可部署前端产物放进 resources/static,一个 jar 同时供出 /student、/admin学校内网一台机器、一条命令就能上线
无 Redis 依赖登录 token 存 t_user_token 表,不引缓存中间件部署清单最短:只要 JDK 8 + MySQL 8
微信登录绑定小程序端 wx.login 换 code,后端绑定 openid 并存 token学生不用注册,微信一键进考试
消息中心t_message / t_message_user 记录发送与已读通知考试安排不必靠微信群吼
Excel 导入导出管理端带 xlsx、file-saver批量导学生名单、导成绩,避免手工点录
图片上传可托管后端接七牛云 SDK,也支持前端直传鉴权(/api/admin/upload/auth)题目图片不占应用服务器磁盘

3. 技术架构

整体结构:单体 Spring Boot 应用 + 两个独立 SPA + 一个原生小程序。没有注册中心、没有消息队列、没有 Redis,属于「一台 4C8G 能扛一个学校」的经典单体。

层技术说明
后端框架Spring Boot 2.1.6.RELEASE2019 年的版本,maven.compiler.target 为 1.8
Web 容器Undertowpom 里显式排除了 tomcat;io-threads: 16、worker-threads: 4000
持久层MyBatis 2.1.0 + PageHelper 1.2.1213 个 Mapper XML,放在 resources/mapper/
安全Spring Security登录口令用 RSA 公钥加密后传输(system.pwdKey),白名单在 security-ignore-urls 里逐条配置
会话自签 token + t_user_token 表不依赖 Redis,token 有效期 token-to-live: 12h
数据库MySQL 8(驱动 8.0.17)连接串带 allowMultiQueries=true,批量 SQL 依赖这个参数
对象存储七牛云 SDK 7.2.25配置项 system.qn(url / bucket / access-key / secret-key)
管理端Vue 2.7.16 + Element UI 2.15 + Vuex 3 + vue-router 3vue-cli 4.5,dev 端口 8002,/api 代理到 8000
学生端同栈dev 端口 8001,outputDir 为 student
小程序微信原生(WXML/WXSS)+ iView WeapplibVersion 2.8.0,接口地址写在 app.js 的 globalData.baseAPI
构建Maven(含 mvnw)+ spring-boot-maven-plugin前端 vue-cli-service build --mode prod

后端分层(com.mindskip.xzs):

包职责
controller/admin、controller/student、controller/wx三端接口分开写,权限边界清晰
service业务逻辑,试卷组卷、判分、任务下发都在这里
repositoryMyBatis Mapper 接口,SQL 在 resources/mapper/*.xml
domain数据库实体,字段与表一一对应
viewmodel出入参 DTO/VO,避免实体直接透出
configurationSecurity、Web、上传等配置
context当前登录用户上下文(ThreadLocal)
event / listener事件驱动(如答卷提交后触发后续处理)
utility / exception / base加密、响应包装、全局异常

几个关键取舍:

  • 不引 Redis:省了一个组件,但每次鉴权都要查一次 MySQL。几百人同时在线没问题,千人级并发考试时数据库会先到瓶颈。
  • Spring Boot 2.1 + Java 8:好处是能跑在几乎任何老服务器、老宝塔环境上;坏处是这个分支早已结束维护,Spring Security 也是 5.1 语法,想升到 3.x 基本等于重写安全配置。
  • Vue 2 + Element UI:2023 年底 Vue 2 已停止维护,Element UI 同样不再迭代,配套的 node-sass 6 只能配 Node 14–16。这不是本项目的问题,是这类 2019 年前后项目的通病。
  • 小程序用原生而不是 uni-app:包体小、微信能力调用直接;代价是同一套学生端页面写了两遍(Web 一遍、小程序一遍)。

4. 目录结构

路径用途
source/xzs/Maven 后端工程,入口 XzsApplication.java
source/xzs/src/main/resources/application.yml主配置:端口 8000、Security 白名单、RSA 密钥对、微信 appid、七牛密钥、token 有效期
source/xzs/src/main/resources/application-{dev,pre,prod,test}.yml分环境数据源,只有 datasource 与日志路径
source/xzs/src/main/resources/mapper/13 个 MyBatis XML,按表拆分(试卷、题目、用户、消息、日志等)
source/xzs/src/main/resources/static/{admin,student}/集成部署时放前端产物,/admin、/student 由此供出
source/vue/xzs-admin/管理端源码,outputDir: 'admin'
source/vue/xzs-student/学生端源码,outputDir: 'student'
source/wx/xzs-student/微信小程序源码(app.js / pages / component / utils / wxs)
sql/xzs-mysql.sql建库 + 13 张表结构 + 2 条用户记录,无题库数据
release/java/xzs-3.9.0.jar官方编译好的 jar,直接可跑(配置仍是默认的 root/123456)
release/web/{admin,student}/官方编译好的前端静态文件
docker/docker-compose.ymlMySQL 8.0.33 + Java 1.8 两容器,端口 8000
docker/install/docker-compose-linux-x86_64仓库里直接塞了一个 docker-compose 二进制(x86_64)
docs/VuePress 文档站的构建产物(HTML),源文档不在仓库里
README.md / LICENSE功能清单与 AGPL-3.0 全文

仓库里有两处不太常见的做法值得注意:release/ 把编译产物直接提交进 Git,好处是「不懂 Maven 也能上线」,坏处是仓库体积和 diff 噪音;source/vue/*/ 下各有一个 node_modules.zip,把依赖打包塞进了源码目录。

5. 快速上手

路线 A:先用官方包跑通(最快)

# 1. 建库并导入结构:脚本自带 CREATE DATABASE,登录 MySQL 后执行
#    source /path/to/sql/xzs-mysql.sql

# 2. 启动(数据源务必换掉默认的 root/123456,见 application-prod.yml)
export SPRING_DATASOURCE_USERNAME=你的账号
export SPRING_DATASOURCE_PASSWORD=你的密码
java -Duser.timezone=Asia/Shanghai -jar release/java/xzs-3.9.0.jar --spring.profiles.active=prod

启动后访问 http://服务器IP:8000/student 与 /admin。前端产物已经在 jar 的 static/ 里,不需要单独部署 Nginx。

路线 B:docker-compose

# compose 把 ./sql 挂到 MySQL 初始化目录,先把脚本放进去
cp sql/xzs-mysql.sql docker/sql/
cd docker
docker compose up -d

注意两点:compose 里 MySQL 的 root 密码写死为 123456,Java 容器用 network_mode: host 加 privileged: true;./log 目录要先建好,否则挂载会失败。

路线 C:前端二次开发

cd source/vue/xzs-admin
npm config set sass_binary_site https://npmmirror.com/mirrors/node-sass
npm install --registry=https://registry.npmmirror.com
npm run serve        # 8002,/api 代理到 localhost:8000

学生端同样操作,端口 8001。Node 必须是 14 或 16:node-sass@6 在 Node 17+ 上装不上。如果本机只有 Node 18/20,最省事的做法是卸掉 node-sass,改装 sass + sass-loader@10。

路线 D:微信小程序

  1. 用微信开发者工具导入 source/wx/xzs-student;
  2. 把 project.config.json 的 appid 换成自己的;
  3. 改 app.js 里 globalData.baseAPI,从 http://localhost:8000 改成自己的 https 域名;
  4. 在小程序后台配置 request 合法域名,开发阶段可勾「不校验合法域名」。

6. 功能模块清单

学生端(Web 与小程序功能一致)

模块说明
登录 / 注册用户名密码;注册时选年级
任务中心管理员按年级下发的任务,每人只能做一次
考试题干支持文本、图片、公式、表格,答题以文本为主
固定试卷可重复练习、自行批改
时段试卷在限定时间窗口内可反复练习
考试记录查看历史答卷与试卷信息
错题本答错自动入库,可回看题目
个人信息 / 更新信息资料、头像修改
个人动态最近行为记录(t_user_event_log)
消息中心接收管理员消息并标记已读

管理端

模块说明
仪表盘试卷数、题目数、用户活跃度、月度题量
学生管理增删改查、禁用、Excel 导入导出
管理员管理增删改查、禁用
学科管理按年级建学科、改名、删除
试卷管理查询、编辑、删除;创建固定/时段/任务试卷
题目管理五种题型,题干富文本(图片、表格、公式)
任务管理按年级下发,控制完成次数
消息管理群发消息、查看已读人数
用户日志全站操作日志
个人资料姓名、手机号、创建时间线

7. 版本与授权

项实际情况
版本号3.9.0,pom.xml、xzs-admin/package.json、xzs-student/package.json、release/java/xzs-3.9.0.jar 四处一致
Git 标签 / Release没有。Gitee API 返回的 tags 与 releases 均为空数组,版本只能看 release 目录里的 jar 名和提交记录
许可证AGPL-3.0(LICENSE 全文、pom.xml 的 licenses 节点、Gitee 项目信息一致)
版权方武汉思维跳跃科技有限公司,官网版权标注 2020–2026
更新节奏近期提交以「教程更新」「组件升级」「bug fix」为主,2026-11 仍在提交

AGPL-3.0 这一点值得单独说明,因为它是本次选型里最容易踩的合规坑:

  • 你可以免费自用、改造、内部部署;
  • 但只要把改造后的系统通过网络提供给外部用户使用(典型的 SaaS 考试平台、对外培训平台),就必须向使用者提供完整源码,包括你的修改;
  • 想闭源商用,只有两条路:买官方商业授权,或者自己从零重写。

如果你只是学校/公司内部用,这不影响;如果你打算拿它做对外的付费考试服务,先算清这条。

8. 商业模式说明

开源仓库本身不收钱,也没有「开源版 + 企业版仓库」的分裂。官方把商业化放在官网,用三档产品做区分。以下三档的对照来自官网产品页(2026-11 抓取):

维度学之思(开源版)维多多(高级版)思多多(旗舰版)
界面设计标准高级高级
后台技术栈Spring Boot / MyBatis / Vue2 / Element UI增加 Redis,仍是 Vue2Vue3 / Element Plus
小程序端微信原生微信原生uni-app(小程序、H5、安卓、iOS)
商业授权无有有
技术支持无有有
内网部署无有有

也就是说:开源版拿走了「能用」,商业版卖的是「能商用 + 有人管 + 能上多端」。

另外,README 和部署文档里反复出现的「数据库脚本领取地址 https://www.mindskip.net:999」是文档站,教程与视频教程也在那里。仓库里的 SQL 只有表结构,完整数据要按官网指引获取——这一步的授权范围以官方说明为准,别默认「代码 AGPL 就等于所有配套资源随便用」。

作者的变现路径很清晰:商业授权 + 定制开发 + 部署服务,外加两个同源商业产品。这也是这类国产开源项目的标准打法。

9. 生态与周边

项目 / 资源作用地址
mindskip/xzs-mysqlMySQL 版本仓库(本文对象)gitee.com/mindskip/xzs-mysql
mindskip/uexamPostgreSQL 版本,功能同源gitee.com/mindskip/uexam
GitHub 镜像mindskip/xzs-mysql、mindskip/xzs(PG 版)github.com/mindskip
GitCode 镜像同上两套gitcode.com/mindskip
官网文档站部署教程、开发文档、数据库脚本指引www.mindskip.net:999
视频教程B 站官方账号space.bilibili.com/1389892305
技术交流QQ 群 18:700540955—
商业产品维多多培训考试系统、思多多智能考试系统www.mindskip.net/wdd.html、/sdd.html
容器镜像阿里云 registry.cn-hangzhou.aliyuncs.com/mindskip/{mysql,java}仅这两个,非官方 Docker Hub

生态上有一个空白要提醒:没有 uni-app / 移动 App 版本,也没有官方 Helm、K8s 清单。docker 目录给的是最朴素的 compose,多实例部署、灰度、水平扩容都得自己做。

10. 选型建议

适合你,如果:

  • 场景是学校、培训机构、企业内部考核,几百到几千人规模;
  • 必须私有化/内网部署,数据不能出机房;
  • 团队会 Java、能读 Spring Boot,愿意接一个「结构清楚但版本偏老」的工程;
  • 需要一个功能闭环的底座(题库、组卷、考试、错题、消息),在此基础上改业务;
  • 想要微信小程序考试,但不想为小程序单独写一套后端。

不适合你,如果:

  • 要做对外经营的 SaaS 考试平台且不打算开源改造后的代码(AGPL 卡在这里);
  • 对前端技术栈有要求(Vue3 / TypeScript),或需要长期安全维护承诺;
  • 预期「万人在线同时开考」——没有 Redis、没有队列,判分与写入全压在 MySQL 上;
  • 需要移动 App、需要多租户隔离、需要直播/防作弊等考场管控能力;
  • 只想白嫖题库:这套系统的价值在流程,不在内容。

和同类怎么比:市面上的开源考试系统大致分两类——一类像本项目,单体 + 完整业务闭环,装完就能用;另一类偏「考试引擎」或前端模板,需要自己接题库与判分。本项目的优势是部署路径短、功能齐、三端都有,劣势是技术债明显、无版本标签、文档站与代码分离。如果你能接受「2019 年的技术栈」,它是同价位里最省心的选择;如果你要的是能长期演进的地基,建议把它当参考实现而不是最终底座。

11. 风险与坑

  • 配置文件里躺着真密钥:application.yml 明文存了 RSA 公私钥对(登录口令加密用)、七牛云的 AccessKey/SecretKey、微信小程序 appid,application-prod.yml 里数据库是 root/123456,docker-compose.yml 的 MySQL root 密码也是 123456。上线前把这些全部换掉;如果这些是对方真实在用的凭据,建议同步轮换。
  • RSA 私钥公开的后果:口令加密的意义在于防明文传输,私钥进了公开仓库,等于这层保护只剩「防君子」。别照抄这段配置。
  • SQL 里没有题库:sql/xzs-mysql.sql 只有 13 张表 + student/admin 两条用户记录,导入后是一个空系统。README 与部署文档都指向官网文档站领取完整脚本,这一步别跳过,也别指望 demo 数据。
  • 默认口令别猜:两个初始用户的密码哈希相同,说明是同一口令;官网演示站给的示例是 student / 123456,但那是对应商业版的演示环境,开源版初始口令以官方文档为准,登不进去就按文档重置。
  • docker/ 里塞了二进制:docker/install/docker-compose-linux-x86_64 是仓库直接提交的二进制文件;compose 又用了 privileged: true + network_mode: host。生产环境建议换成发行版自带的 docker compose 插件,并去掉特权。
  • 前端目录里有 node_modules.zip:xzs-admin 与 xzs-student 各一份,clone 时间会明显变长,别误当成依赖清单。
  • Node 版本陷阱:node-sass@6 + vue-cli@4 只认 Node 14–16;Node 18/20 上 npm install 直接编译失败。要么降 Node,要么换 dart-sass。
  • Spring Boot 2.1.6 已 EOL:这个分支 2019 年就停止维护了,Undertow、Jackson 等传递依赖的已知漏洞要自己评估;Spring Security 5.1 的写法与 5.7/6.x 差异很大,升级成本接近重写。
  • 集成部署的路径要求死:前端产物必须放到 source/xzs/src/main/resources/static/ 下的 admin、student 两个目录,publicPath 是 './',放错一层就是白屏。
  • 小程序接口地址写死在代码里:app.js 的 baseAPI 是 http://localhost:8000,真机必须改成 https 域名并配好白名单,否则所有请求静默失败。
  • 学生端带了别人的统计代码:source/vue/xzs-student/public/index.html 里内嵌了百度统计脚本(站点 ID cd8218cd...),自建站点要删掉,否则访客数据进了别人的统计账号。
  • 没有版本标签:想追变更只能翻提交记录,升级时无法用「3.8.0 → 3.9.0 的 changelog」判断影响面。
  • 时区:启动参数必须带 -Duser.timezone=Asia/Shanghai,时段试卷的开考与截止时间依赖它;容器默认 UTC 会导致时间窗口错 8 小时。
  • 数据库连接串的 allowMultiQueries=true:后端有批量 SQL 依赖这个参数,自建连接池时漏掉会报错。

12. 参考链接

名称地址
代码仓库(Gitee,MySQL 版)https://gitee.com/mindskip/xzs-mysql
代码仓库(PostgreSQL 版)https://gitee.com/mindskip/uexam
GitHub 镜像https://github.com/mindskip/xzs-mysql
官网https://www.mindskip.net
学之思产品页https://www.mindskip.net/xzs.html
商业授权与购买https://www.mindskip.net/buy.html
文档站https://www.mindskip.net:999
学生端在线演示https://www.mindskip.net:7001
教师端在线演示https://www.mindskip.net:7002
视频教程https://space.bilibili.com/1389892305
AGPL-3.0 协议全文https://www.gnu.org/licenses/agpl-3.0.txt

本文基于 2026-11-10 的 master 分支源码(pom.xml、application.yml、vue.config.js、package.json、sql 脚本、docker 配置)、Gitee API 数据与官网产品页整理;Star 数、版本号、模块清单均以该日为准,后续迭代请以仓库实际内容为准。*

标签: 考试系统, Java, Vue

添加新评论