SpringBoot+Vue构建问卷调查系统的技术实践

1. 项目概述

这个基于SpringBoot+Vue+MySQL的问卷调查系统是一个典型的毕业设计项目,它完整实现了问卷创建、发布、填写和统计分析的闭环流程。作为前后端分离架构的实践案例,它既包含了基础CRUD功能,又涉及了数据可视化、权限控制等进阶特性,非常适合作为计算机相关专业学生的综合实践项目。

我在实际开发过程中发现,这类系统虽然业务逻辑不复杂,但要处理好前后端数据交互、问卷逻辑验证和响应式展示等细节,仍然需要扎实的编程基础。特别是当问卷题目包含多种类型(单选、多选、填空等)时,数据结构设计和状态管理就变得尤为关键。

2. 技术栈选型解析

2.1 后端技术组合

SpringBoot 2.7 + MyBatis-Plus构成了后端核心框架,这种组合在毕业设计中非常常见:

  • SpringBoot的自动配置特性大幅简化了SSM框架的整合难度
  • MyBatis-Plus的代码生成器可以快速产出基础CRUD代码
  • 内置的Tomcat服务器方便本地测试和部署

数据库选用MySQL 8.0,主要考虑因素包括:

  • 对JSON字段的良好支持(用于存储动态问卷结构)
  • 事务特性保证数据一致性
  • 完善的索引机制提升查询效率

实际开发中发现,当问卷回收量超过10万条时,需要在answer表上建立复合索引(questionnaire_id, submit_time)来优化统计查询性能。

2.2 前端技术方案

Vue 3 + Element Plus构建的管理后台具有以下优势:

  • Composition API使逻辑复用更灵活
  • 基于Proxy的响应式系统性能更好
  • Element Plus的Form组件非常适合问卷编辑场景

前端工程化配置要点:

// vue.config.js关键配置 module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } }, chainWebpack: config => { config.plugin('html').tap(args => { args[0].title = '问卷调查系统' return args }) } }

3. 核心功能实现细节

3.1 问卷模型设计

采用三层级数据结构设计:

  1. questionnaire表存储问卷元信息
  2. question表记录题目内容及类型
  3. option表保存选择题选项
// 问卷实体关系示例 public class Questionnaire { private Long id; private String title; private Date createTime; @TableField(typeHandler = JacksonTypeHandler.class) private List<Question> questions; } public class Question { private Integer type; //1单选 2多选 3填空 private String content; private List<Option> options; }

3.2 动态表单渲染

前端根据题目类型动态渲染不同组件:

<template v-for="(q,index) in questions" :key="q.id"> <el-radio-group v-if="q.type===1" v-model="answers[index]"> <el-radio v-for="opt in q.options" :label="opt.id">{{opt.text}}</el-radio> </el-radio-group> <el-checkbox-group v-else-if="q.type===2" v-model="answers[index]"> <el-checkbox v-for="opt in q.options" :label="opt.id">{{opt.text}}</el-checkbox> </el-checkbox-group> <el-input v-else v-model="answers[index]" /> </template>

3.3 数据统计可视化

使用ECharts实现多维数据分析:

// 饼图配置示例 const option = { tooltip: { trigger: 'item' }, series: [{ type: 'pie', radius: '70%', data: statData.map(item => ({ value: item.count, name: item.optionText })) }] }

4. 项目部署实践

4.1 后端部署要点

  1. 打包时排除开发依赖:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin>
  1. 生产环境配置建议:
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/survey?useSSL=false&serverTimezone=Asia/Shanghai username: survey_prod password: ${DB_PASSWORD} redis: host: 127.0.0.1 port: 6379 password: ${REDIS_PASS}

4.2 前端部署优化

  1. 配置nginx反向代理:
server { listen 80; server_name survey.example.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } }
  1. 开启Gzip压缩:
// vite.config.js export default defineConfig({ plugins: [vue()], build: { chunkSizeWarningLimit: 1500, rollupOptions: { output: { manualChunks(id) { if (id.includes('node_modules')) { return 'vendor' } } } } }, server: { proxy: { '/api': 'http://localhost:8080' } } })

5. 开发经验与避坑指南

5.1 常见问题解决方案

  1. 跨域问题处理:
  • 开发环境:配置vue-cli代理
  • 生产环境:Nginx反向代理
  • 备用方案:SpringBoot添加CORS配置
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .maxAge(3600); } }
  1. 大文件上传优化:
  • 前端分片上传
  • 后端合并文件
  • Nginx调整client_max_body_size

5.2 性能优化建议

  1. 缓存策略:
@Cacheable(value = "questionnaire", key = "#id") public Questionnaire getById(Long id) { return getById(id); }
  1. 异步处理:
@Async public void exportStatistics(Long questionnaireId, HttpServletResponse response) { // 耗时统计操作 }
  1. 数据库优化:
-- 为常用查询添加索引 CREATE INDEX idx_answer ON answer(questionnaire_id, question_id);

6. 论文写作要点

  1. 技术选型章节应包含:
  • 框架对比表格(SpringBoot vs 传统SSM)
  • 前端技术演进路线
  • 数据库选型依据
  1. 系统设计章节建议结构:
  • 架构图(分层设计)
  • 核心类图
  • 数据库ER图
  • 关键流程图
  1. 测试方案设计:
  • JMeter压力测试脚本
  • Selenium自动化测试用例
  • Postman接口测试集合

这个项目最值得深入挖掘的是动态表单的设计实现,我在开发过程中尝试过三种方案:纯JSON Schema、基于配置的组件映射、以及最终采用的类型驱动渲染。实测发现类型驱动方案在扩展性和性能之间取得了最佳平衡,新增题目类型只需添加对应的Vue组件即可。