以下是基于Spring Boot的问卷调查系统的技术栈、功能设计、数据库及测试设计的详细方案:


技术栈

后端

  • 框架:Spring Boot 2.7.x(集成Spring MVC、Spring Security)
  • 数据库:MySQL 8.0(关系型存储)/ MongoDB(可选,用于非结构化数据)
  • ORM:MyBatis-Plus/JPA(根据团队习惯选择)
  • 缓存:Redis(存储高频访问的问卷模板或结果)
  • 消息队列:RabbitMQ(异步处理大批量提交)

前端

  • 核心框架:Vue 3 + Element Plus(或React + Ant Design)
  • 构建工具:Vite/Webpack
  • 可视化:ECharts(统计结果展示)

测试

  • 单元测试:JUnit 5 + Mockito
  • 集成测试:TestContainers(数据库容器化测试)
  • 压力测试:JMeter

功能模块设计

1. 用户管理

  • 角色划分:管理员、问卷创建者、普通用户
  • JWT鉴权:基于Spring Security实现登录/权限控制

2. 问卷管理

  • 创建问卷:支持单选、多选、评分、文本输入等题型
  • 逻辑跳转:根据用户答案动态跳转到指定问题
  • 模板库:预置常用问卷模板(如满意度调查)

3. 答卷与统计

  • 实时提交:前端校验 + 后端防重复提交(Redis分布式锁)
  • 数据看板:按时间、用户分组统计结果
  • 导出功能:Excel/PDF导出(Apache POI + iText)

4. 系统扩展

  • API开放:Restful接口供第三方调用
  • Webhook:问卷提交后触发外部系统通知

数据库设计(MySQL示例)

表结构

-- 问卷表
CREATE TABLE `survey` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
  `title` VARCHAR(255) NOT NULL,
  `description` TEXT,
  `creator_id` BIGINT NOT NULL,
  `start_time` DATETIME,
  `end_time` DATETIME,
  `status` ENUM('draft', 'published', 'closed')
);

-- 问题表
CREATE TABLE `question` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
  `survey_id` BIGINT NOT NULL,
  `content` TEXT NOT NULL,
  `type` ENUM('single_choice', 'multiple_choice', 'text', 'rating'),
  `is_required` BOOLEAN DEFAULT FALSE,
  FOREIGN KEY (`survey_id`) REFERENCES `survey`(`id`)
);

-- 选项表(针对选择题)
CREATE TABLE `option` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
  `question_id` BIGINT NOT NULL,
  `content` VARCHAR(255) NOT NULL,
  FOREIGN KEY (`question_id`) REFERENCES `question`(`id`)
);

-- 回答表
CREATE TABLE `answer` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
  `question_id` BIGINT NOT NULL,
  `user_id` BIGINT,
  `response` TEXT,  -- 文本答案或选项ID集合
  FOREIGN KEY (`question_id`) REFERENCES `question`(`id`)
);


系统测试设计

1. 单元测试覆盖率

  • Service层:Mock数据库操作,验证业务逻辑(如问卷状态流转)
  • Controller层:@WebMvcTest测试API响应格式与状态码

2. 集成测试场景

  • 并发提交:使用JMeter模拟1000+用户同时提交问卷
  • 数据一致性:TestContainers启动MySQL容器,验证事务回滚机制

3. 安全测试

  • OWASP ZAP扫描:检测XSS/SQL注入风险
  • 权限验证:非管理员用户尝试访问管理接口应返回403

源码结构建议

src/
├── main/
│   ├── java/
│   │   └── com/survey/
│   │       ├── config/       # Spring配置类
│   │       ├── controller/   # 按功能划分(SurveyController.java)
│   │       ├── service/      # 接口+实现分离
│   │       ├── repository/   # MyBatis Mapper或JPA接口
│   │       └── entity/       # 数据库实体类
│   └── resources/
│       ├── static/           # 前端构建产物
│       └── application.yml   # 多环境配置
└── test/
    ├── java/                 # 测试代码镜像main结构
    └── resources/            # 测试数据(survey_data.json)


关键实现片段(Spring Boot + MyBatis-Plus)

动态问题跳转逻辑

// 在Service层处理跳转规则
public Question getNextQuestion(Long surveyId, Long currentQId, Map<String, String> userAnswers) {
    LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Question::getSurveyId, surveyId)
           .gt(Question::getId, currentQId)  // 获取当前问题之后的题目
           .orderByAsc(Question::getId)
           .last("LIMIT 1");
    Question nextQuestion = questionMapper.selectOne(wrapper);
    
    // 根据用户答案匹配跳转规则(需提前配置)
    JumpRule rule = ruleMapper.selectByQuestion(currentQId);
    if (rule != null && rule.getTargetAnswer().equals(userAnswers.get(currentQId))) {
        return questionMapper.selectById(rule.getJumpTo());
    }
    return nextQuestion;
}

统计结果聚合查询

-- 获取单选题选项分布
SELECT o.content, COUNT(a.id) AS count 
FROM answer a 
JOIN option o ON FIND_IN_SET(o.id, a.response) > 0
WHERE a.question_id = #{questionId}
GROUP BY o.id;


以上设计可根据实际需求调整技术选型(如用MongoDB存储非结构化问卷数据),重点在于清晰的模块划分和可扩展性。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐