云帆培训考试系统二次开发指南:如何新增题型、对接企业自有用户系统
【免费下载链接】yftrain学习系统-在线考试系统 企业培训内训系统-企教培系统平台软件项目地址: https://gitcode.com/gh_mirrors/yf/yftrain
云帆培训考试系统(yftrain)是一款开源的在线考试系统 / 企业培训内训平台,采用 Spring Boot + Vue 架构,开箱即用,也极易二次开发。本文以"如何新增题型"和"如何对接企业自有用户系统"这两个最常见的改造需求为主线,带你快速定位核心源码,掌握培训考试系统二次开发的完整思路。
一、系统架构速览:改动前先看"地图"
整个系统分为前后端两个工程,职责清晰:
- exam-api:Java 后端(Spring Boot + Shiro + JWT + MyBatis-Plus),业务代码集中在
exam-api/src/main/java/com/yf/exam/modules/下,按模块拆分:qu:题库与题目(题目、选项、题库管理)paper:试卷生成、答题、判分exam:考试发布与规则sys:系统管理(用户、角色、部门、配置)user:学员端(考试、培训)
- exam-vue:Vue 前端,管理端页面在
exam-vue/src/views/下 - docs/安装资源/数据库脚本.sql:完整建库脚本,所有数据表结构一目了然
理解一个模块只需记住固定的四层套路:Controller(接口)→ Service(业务)→ Mapper(SQL)→ Entity(表结构),二次开发时按这条链路逐层修改即可。
二、如何新增题型:以"问答题"为例
系统默认支持三种题型:单选题、多选题、判断题,全部由一个枚举接口统一定义,扩展点非常集中。
1. 题型定义在哪里
- 后端题型常量:QuType.java,
RADIO=1(单选)、MULTI=2(多选)、JUDGE=3(判断) - 数据库字段:
el_qu表的qu_type列(见 数据库脚本.sql),无需改表结构,新增题型只是多了一个数字 - 前端题型下拉框:form.vue 中的
quTypes数组
💡 一个有意思的细节:form.vue 里已存在
postForm.quType !== 4的判断分支——为"第 4 种题型(主观题)"预留了扩展位,官方也推荐用它承载问答题。
2. 新增题型五步走
以新增问答题(quType=4)为例:
| 步骤 | 改哪里 | 做什么 |
|---|---|---|
| ① 定义常量 | QuType.java | 增加Integer ESSAY = 4 |
| ② 保存校验 | QuServiceImpl.java 的checkData | 问答题没有标准选项,需跳过"至少一个正确项"的客观题校验 |
| ③ 组卷与分值 | PaperServiceImpl.java 的generateByRepo/processPaperQu | 仿照单选/多选分支,按考试规则中的问答题数量抽题并赋分 |
| ④ 判分逻辑 | PaperQuAnswerServiceImpl.java | 问答题无法自动判对错,改为"待人工阅卷"或留空不判分 |
| ⑤ 前端展示 | exam.vue 与 form.vue | 题型下拉增加"问答题";答题页用文本域替代单选/多选组件 |
3. 别忘了考试规则配置
考试与题库的绑定关系存在el_exam_repo表中,单选数/多选数/判断数各有独立的"数量 + 分值"字段(对应ExamRepoDTO的radioCount、multiScore等属性)。若要支持问答题数量配置,需要:
- 给
el_exam_repo表加两列(如essay_count、essay_score) - 同步修改 ExamRepoDTO.java 实体
- 在 exam.vue 的考试规则表单中增加输入框
完成后,学员端答题页(exam-vue/src/views/paper/exam/exam.vue)会按题型分组渲染题卡,问答题自然会被新分支接管。
三、如何对接企业自有用户系统
企业落地时最常见的诉求:员工用企业账号体系(AD/LDAP、钉钉、内部 OA)直接登录考试系统,而不是在系统里另建一套账号。
1. 先看懂现有登录机制
登录链路集中在sys/user模块:
- 接口入口:SysUserController.java,提供
login、reg(注册)、quick-reg(手机号快注)、info(获取会话)等接口 - 认证逻辑:SysUserServiceImpl.java 的
login方法——按用户名查sys_user表,用 PassHandler.java 做"盐值 + 密码"校验 - 会话机制:Shiro + JWT(JwtUtils.java),登录成功后用
JwtUtils.sign(username)签发 Token,后续请求由 JWT 过滤器校验 - 获取当前用户:任何 Service 里都可以调用 UserUtils.java 的
getUserId() - 权限模型:用户通过
sys_user_role关联角色,sa为超级管理员、student为学员(见 SysUserRoleServiceImpl.java)
2. 方案 A:账号批量同步(推荐,改动最小)
适合"企业仍想用独立登录页,但用户数据来自 HR/OA"的场景:
- 在企业用户系统侧新增一个用户同步接口,遍历本企业账号
- 调用考试系统的用户保存逻辑(SysUserServiceImpl.java 的
save方法,或管理端/exam/api/sys/user/save接口)写入sys_user表,并绑定部门(departId对应sys_depart表)与学员角色 - 员工用同步过来的账号密码登录,部门、角色关系自动生效,后续组织架构调整再增量同步即可
⚠️ 密码建议用 PassHandler.java 生成盐值后再入库,与内置用户保持一致的加密方式。
3. 方案 B:SSO 单点登录(体验最佳)
适合"从 OA/门户点击直达考试系统,免输账号密码"的场景,核心思路是:用企业侧的合法凭证换取一个 JWT Token。
- 在 SysUserController.java 中新增一个
/sso-login接口,接收企业侧签名(如 AES 加密的 userId 或企业 SSO 回调 ticket) - 校验签名后,查/建本地用户,仿照
setToken方法用JwtUtils.sign(username)签发 Token 返回 - 前端拿到 Token 后写入本地(参考 auth.js 的
getToken/setToken),再调用/exam/api/sys/user/info换取用户信息,登录流程与内置登录完全一致 - 免登录场景下,可参考 ShiroConfig.java 调整过滤链,让
/sso-login接口匿名可访问
由于后续所有接口都基于 Shiro 会话取用户,SSO 只改"进门"这一步,系统内部无需任何改动,这也是本系统对接成本低的根本原因。
四、关键文件清单(二次开发速查)
| 需求 | 关键文件 |
|---|---|
| 题型定义与保存 | QuType.java、QuServiceImpl.java |
| 组卷 / 判分 | PaperServiceImpl.java、PaperQuAnswerServiceImpl.java |
| 题目 / 答题前端 | qu/form.vue、exam.vue |
| 登录与用户 | SysUserController.java、SysUserServiceImpl.java |
| 安全与会话 | ShiroConfig.java、JwtUtils.java |
| 数据表结构 | 数据库脚本.sql |
| 部署与运行资料 | docs/运行包/运行说明.txt、docs/部署手册.pdf |
五、常见疑问
Q1:新增题型一定要改数据库吗?不需要。qu_type只是el_qu表中的一个整型字段,新题型只是新增值;只有想给新题型配置"独立数量/分值"时才需要给el_exam_repo加列。
Q2:对接用户系统会影响原有登录吗?不会。方案 B 是"新增"一条登录入口,原有账号密码登录、注册、快捷登录接口全部保留,可以两套并存、平滑过渡。
Q3:修改后如何验证?用 admin 账号登录管理端,走一遍"建题库 → 录入新题型题目 → 配置考试规则 → 学员端答题 → 查看成绩单"的完整闭环,判分和报表正常即改造完成。
掌握以上两条主线,再结合固定的"Controller → Service → Mapper"分层结构,培训考试系统的绝大多数二次开发需求都能快速落地 🚀
【免费下载链接】yftrain学习系统-在线考试系统 企业培训内训系统-企教培系统平台软件项目地址: https://gitcode.com/gh_mirrors/yf/yftrain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考