原创

基于SpringBoot2+vue2的在线问卷调查系统

温馨提示:
本文最后更新于 2026年06月03日,已超过 7 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

1. 资源

放到最后面

2. 项目简介

在线问卷调查系统,旨在提供一个平台供管理员创建和管理问卷,并允许用户(受访者)在线参与问卷调查。系统核心功能围绕问卷的“创建-发布-填写-记录”这一完整流程展开。

系统包含两个主要角色:

  • 管理员:负责后台管理,包括问卷管理、题目管理、用户管理、新闻资讯管理以及系统配置(如轮播图)等。
  • 普通用户:可以浏览和填写已发布的问卷,查看自己的历史问卷调查记录,并浏览系统发布的新闻资讯。

3. 技术栈

该项目是一个典型的前后端分离Web应用,主要技术构成如下:

  • 后端框架: Spring Boot 2.2.2.RELEASE
  • ORM/数据访问层: MyBatis Plus 2.3 (集成MyBatis)
  • 权限控制: Apache Shiro 1.3.2
  • 数据库: MySQL 5.7.32-log
  • 前端(管理后台): Vue.js (使用Element UI组件库)
  • 前端(用户端): Layui, HTML/CSS/JavaScript, Vue.js (部分使用)
  • 其他关键库: fastjson, commons-lang3, poi (用于Excel导入导出)

    4. 详细介绍

    4.1 核心功能模块

  • 用户管理模块:

    • 用户端: 提供用户注册、登录功能。用户可以完善个人信息,如姓名、性别、身份证号、手机号等。
    • 管理端: 管理员可以在后台查看、新增、修改、删除用户信息。
  • 问卷管理模块:

    • 管理端: 管理员可以创建新的问卷,设置问卷名称、答卷时长。可以对问卷进行启用/禁用操作。
    • 用户端: 用户登录后,可以看到所有状态为“启用”的问卷列表,并选择问卷进行填写。
  • 题目管理模块:

    • 管理端: 管理员可以为指定的问卷添加题目。题目支持单选题多选题两种类型。每道题可以设置多个选项和题目排序。
    • 用户端: 用户在答题时,系统会根据题目类型呈现单选按钮或多选框,并记录用户的选项。
  • 答卷与记录模块:

    • 用户端: 用户开始答题时,系统会生成一次唯一的问卷调查记录。答题过程受前端设置的时长限制,用户可以在规定时间内逐题作答。提交后,用户的每道题答案都会被保存。
    • 管理端与用户端: 答题结束后,系统会生成一条包含答卷编号、用户信息、答卷时间的记录。用户和管理员都可以查看答卷的详细内容和用户的选项。
  • 新闻资讯模块:

    • 管理端: 管理员可以发布、修改、删除新闻资讯,新闻支持分类。
    • 用户端: 用户在首页可以查看最新的新闻资讯列表和详情。
  • 系统配置模块:

    • 管理端: 管理员可以配置首页轮播图。

4.2 数据库设计

  • yonghu: 用户表,存储用户账号、密码、姓名、联系方式等信息。
  • exampaper: 问卷表,存储问卷名称、时长和状态(启用/禁用)。
  • examquestion: 题目表,通过 exampaper_idexampaper 表关联。存储题目内容、选项(JSON格式)、题目类型(单选/多选)和排序。
  • examrecord: 问卷调查记录表,记录一次完整的答卷过程,关联用户 (yonghu_id) 和问卷 (exampaper_id)。
  • examredetails: 答题详情表,记录用户在每次问卷 (examrecord) 中对每道题 (examquestion_id) 的具体答案。
  • news: 新闻资讯表。
  • dictionary: 字典表,用于存储系统内的枚举值,如性别(男/女)、问卷状态(启用/禁用)、题目类型(单选/多选)等。
  • users: 管理员表。

5. 部分代码

5.1 后端 - 问卷管理Controller (ExampaperController.java)

此代码片段展示了后端处理问卷分页查询和详情查询的接口逻辑。

// 文件路径: ./zaixianwenjuandiaocha/src/main/java/com/controller/ExampaperController.java
package com.controller;

// ... 省略导入 ...

@RestController
@Controller
@RequestMapping("/exampaper")
public class ExampaperController {
    // ... 依赖注入 ...

    /**
    * 后端列表
    */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
        // 1. 获取用户角色
        String role = String.valueOf(request.getSession().getAttribute("role"));
        // 2. 若为普通用户,则只查询其自己的数据
        if("用户".equals(role))
            params.put("yonghuId",request.getSession().getAttribute("userId"));
        // 3. 调用service层分页查询
        PageUtils page = exampaperService.queryPage(params);
        // 4. 对查询结果中的字典字段进行转换(如状态码转文字)
        List<ExampaperView> list =(List<ExampaperView>)page.getList();
        for(ExampaperView c:list){
            dictionaryService.dictionaryConvert(c, request);
        }
        return R.ok().put("data", page);
    }

    /**
    * 后端详情
    */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id, HttpServletRequest request){
        ExampaperEntity exampaper = exampaperService.selectById(id);
        if(exampaper !=null){
            // 同样进行字典转换后返回
            ExampaperView view = new ExampaperView();
            BeanUtils.copyProperties( exampaper , view );
            dictionaryService.dictionaryConvert(view, request);
            return R.ok().put("data", view);
        }else {
            return R.error(511,"查不到数据");
        }
    }
    // ... 省略保存、修改、删除等方法 ...
}

5.2 前端用户端 - 答题页面核心逻辑 (exam.html)

此代码片段展示了用户答题时的核心前端逻辑,包括数据初始化、选项绑定和答案提交。

<!-- 文件路径: ./zaixianwenjuandiaocha/src/main/resources/front/front/pages/exampaper/exam.html -->
<div id="app" class="container">
    <!-- ... 页面布局 ... -->
</div>

<script type="text/javascript">
    var app = new Vue({
        el: "#app",
        data() {
            return {
                dataList: [], // 所有题目
                currentIndex: 0, // 当前题目索引
                ruleForm: {}, // 当前题目信息
                options: null, // 当前题目的选项
                answer: "", // 用户当前题目的答案
                // ... 其他状态
            };
        },
        methods: {
            init() {
                // 1. 从URL获取问卷ID
                let id = layui.http.getParam("id");
                // 2. 获取当前登录用户信息
                // 3. 加载该问卷下的所有题目
                layui.http.request(`examquestion/page`, 'get', {
                    orderBy: "examquestion_sequence",
                    exampaperId: id
                }, function (data) {
                    app.dataList = data.data.list;
                    app.ruleForm = app.dataList[app.currentIndex];
                    // 4. 解析当前题目的选项(JSON字符串转对象)
                    app.options = JSON.parse(app.ruleForm.examquestionOptions);
                });
                // 5. 加载问卷信息并开始计时...
            },
            submitTap() {
                // 1. 处理多选题答案(数组转逗号分隔字符串)
                if (this.ruleForm.examquestionTypes == 2) {
                    this.answer = this.answer.join(",");
                }
                // 2. 保存当前题目的答题记录到后端
                let record = {
                    examredetailsUuidNumber: layui.http.getParam("paperUUID"),
                    examquestionId: this.ruleForm.id,
                    examredetailsMyanswer: this.answer,
                    yonghuId: this.user.id,
                };
                layui.http.requestJson(`examredetails/saveExamredetails`, 'post', record, function (res) {});
                // 3. 加载下一题,或结束问卷
                if (this.currentIndex == this.dataList.length - 1) {
                    this.isEndFlag = true;
                } else {
                    this.currentIndex++;
                    this.ruleForm = this.dataList[this.currentIndex];
                    this.options = JSON.parse(this.ruleForm.examquestionOptions);
                }
                this.answer = null;
            },
        }
    });
    // ... 初始化调用 ...
</script>

5.3 数据库 - 核心表结构 (db.sql)

此代码片段展示了项目核心的问卷表 (exampaper) 和题目表 (examquestion) 的SQL创建语句。

-- 文件路径: ./db.sql
-- 问卷表
CREATE TABLE `exampaper` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `exampaper_name` varchar(200) NOT NULL COMMENT '问卷名称 Search111',
  `exampaper_date` int(11) NOT NULL COMMENT '时长(分钟)',
  `exampaper_jieshuyu` varchar(255) DEFAULT NULL COMMENT '结束语',
  `exampaper_types` int(11) NOT NULL DEFAULT '0' COMMENT '问卷状态 Search111',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='问卷表';

-- 题目表
CREATE TABLE `examquestion` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `exampaper_id` int(20) NOT NULL COMMENT '所属问卷id(外键)',
  `examquestion_name` varchar(200) NOT NULL COMMENT '试题名称 Search111',
  `examquestion_options` longtext COMMENT '选项',
  `examquestion_types` int(20) DEFAULT '0' COMMENT '试题类型',
  `examquestion_sequence` int(20) DEFAULT '100' COMMENT '试题排序,值越大排越前面',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='试题表';

6. 部分截图

img1
img2
img3
img4
img5
img6
img7
img8
img9
img10
img11
img12
img13
img14
img15
img16
img17
img18
img19
img20
img21
img22
img23
img24
img25
img26
img27
img28
img29
img30

7. 项目总结

在线问卷调查系统是一个功能完备、结构清晰的在线问卷调查系统。

优点与特点

  1. 功能完整:系统覆盖了从问卷创建、题目配置、用户答题到答卷查看的完整业务闭环,满足了线上问卷调查的基本需求。
  2. 角色分明:通过区分管理员和普通用户,实现了清晰的后台管理权和前台使用权,权限控制逻辑简单有效。
  3. 技术栈实用:采用了业界主流的Spring Boot + MyBatis Plus + MySQL作为后端基础,前端则分别使用Vue/Element UI(后台)和Layui(前台),技术选择兼顾了开发效率和界面美观。
  4. 数据设计合理:数据库表结构设计规范,exampaper (问卷)、examquestion (题目)、examrecord (答卷记录) 和 examredetails (答题详情) 四张核心表的关联清晰,能够很好地支持问卷数据的存储和统计分析。
  5. 扩展性良好:通过dictionary字典表来管理枚举值,提高了系统的灵活性和可维护性。集成了ECharts,为后续实现问卷结果的数据可视化分析提供了基础。

总体而言,在线问卷调查系统是一个优秀的教育或调研类Web应用范例,代码结构清晰,功能点明确,非常适合作为Java Spring Boot和Vue.js的学习项目或作为基础框架进行二次开发。

代码:https://fifteen.xiaobias.com/source/153

正文到此结束
本文目录