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

1. Base64 编码

解锁技能,猴子打野出装需 5 大米 ,才能真正驾驭"猴三棒"的暴力美学

鞋子/小野刀/贪婪之噬/暗影战斧/泣血之刃/名刀·司命

铭文组合为8夺萃、1狩猎、1兽痕、5祸源、5无双、10鹰眼

必备技能:Base64 编码解码

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 核心功能模块
  1. 用户管理模块:

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

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

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

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

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

    • 管理端: 管理员可以配置首页轮播图。
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)

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

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)

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

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创建语句。

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. 部分截图

Copy the following content and use base64 decoding to obtain the source code and files.

5aSN5Yi25omT5byA6I635Y+W5rqQ5Luj56CB77yaaHR0cHM6Ly9maWZ0ZWVuLnhpYW9iaWFzLmNvbS9zb3VyY2UvMTUz

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的学习项目或作为基础框架进行二次开发。