xinli/z_Project change/进度汇总/21-问卷功能完整实现方案.md

222 lines
7.3 KiB
Markdown
Raw Normal View History

2025-11-12 15:25:47 +08:00
# 问卷功能完整实现方案
## 📋 需求概述
系统需要支持完整的问卷功能,包括:
1. **问卷在量表管理中显示**:创建的问卷能够出现在量表管理中
2. **问卷答题功能**:用户填写完问卷后,客观题自动打分,主观题传给管理员进行打分
3. **多种题目类型支持**:单选、多选、判断、填空、排序、计算、简答、问答、作文等
4. **多种组卷形式**:自助组卷、随机组卷、手动随机相结合
5. **成绩排名统计**:客观题系统自动实现打分,成绩自动排名统计
---
## 🎯 实现方案
### 阶段一:让问卷显示在量表管理中
#### 方案1统一查询接口推荐
- 修改量表列表查询,同时返回问卷数据
- 添加类型标识字段(`sourceType`: 'scale' 或 'questionnaire'
- 前端统一显示,根据类型标识区分操作
#### 方案2创建统一视图
- 在数据库创建视图,统一量表和问卷
- 查询时使用视图
**选择方案1**,因为更灵活,不需要修改数据库结构。
---
### 阶段二:问卷答题功能
参考量表测评的实现方式:
1. **开始问卷**:创建问卷答题记录
2. **获取题目**:根据组卷方式获取题目列表
3. **保存答案**:实时保存用户答案
4. **提交问卷**
- 客观题自动计分
- 主观题标记为待评分
- 计算客观题总分
- 更新排名
---
### 阶段三:自动打分功能
#### 客观题类型
- **radio单选**:根据选项的`is_correct`和`option_score`计分
- **checkbox多选**:全对得满分,部分对按比例得分
- **boolean判断**:根据选项的`is_correct`计分
- **input填空**:如果有标准答案,进行文本匹配(支持模糊匹配)
- **sort排序**:顺序完全正确得满分,部分正确按比例得分
- **calculate计算**:数值匹配,允许误差范围
#### 主观题类型
- **text简答**:需要管理员评分
- **textarea问答**:需要管理员评分
- **essay作文**:需要管理员评分
- **input无标准答案**:需要管理员评分
---
### 阶段四:主观题评分管理
1. **待评分列表**:显示所有待评分的主观题
2. **评分界面**:管理员可以查看题目、答案,进行评分
3. **批量评分**:支持批量评分功能
4. **评分后更新**:评分后更新总分和排名
---
### 阶段五:成绩排名统计
1. **排名计算**
- 按总分从高到低排序
- 相同分数按提交时间排序(先提交的排名靠前)
2. **排名更新**:提交问卷或评分后自动更新排名
3. **排名查询**:支持按问卷查询排名列表
---
## 📁 需要创建/修改的文件
### 数据库
- [x] `psy_questionnaire` - 问卷表(已存在)
- [x] `psy_questionnaire_item` - 问卷题目表(已存在)
- [x] `psy_questionnaire_option` - 问卷选项表(已存在)
- [x] `psy_questionnaire_answer` - 问卷答题记录表(已存在)
- [ ] `psy_questionnaire_answer_detail` - 问卷答案详情表(需要创建)
### 后端Java文件
- [ ] `PsyQuestionnaireAnswerDetail.java` - 问卷答案详情实体类
- [ ] `PsyQuestionnaireAnswerDetailMapper.java` - Mapper接口
- [ ] `PsyQuestionnaireAnswerDetailMapper.xml` - MyBatis映射
- [ ] `IPsyQuestionnaireAnswerService.java` - 问卷答题服务接口
- [ ] `PsyQuestionnaireAnswerServiceImpl.java` - 问卷答题服务实现
- [ ] `PsyQuestionnaireController.java` - 问卷控制器(需要增强)
- [ ] `PsyScaleController.java` - 量表控制器(需要修改列表查询)
### 前端Vue文件
- [ ] `questionnaire/taking.vue` - 问卷答题页面
- [ ] `questionnaire/start.vue` - 开始问卷页面
- [ ] `questionnaire/scoring.vue` - 主观题评分页面
- [ ] `questionnaire/ranking.vue` - 成绩排名页面
- [ ] `scale/index.vue` - 量表管理页面(需要修改,显示问卷)
---
## 🔧 技术实现细节
### 1. 量表列表统一显示问卷
**后端修改**
```java
// PsyScaleController.java
@GetMapping("/list")
public TableDataInfo list(PsyScale scale, @RequestParam(required = false) Boolean includeQuestionnaire)
{
startPage();
List<PsyScale> scaleList = scaleService.selectScaleList(scale);
// 如果需要包含问卷
if (includeQuestionnaire != null && includeQuestionnaire) {
List<PsyQuestionnaire> questionnaireList = questionnaireService.selectQuestionnaireList(...);
// 转换为统一的Scale格式添加sourceType标识
// 合并到scaleList
}
return getDataTable(scaleList);
}
```
**前端修改**
```javascript
// scale/index.vue
// 在表格中添加类型列
<el-table-column label="类型" prop="sourceType" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.sourceType === 'questionnaire'" type="warning">问卷</el-tag>
<el-tag v-else type="primary">量表</el-tag>
</template>
</el-table-column>
```
### 2. 问卷答题流程
参考量表测评的实现:
1. 开始问卷 → 创建`PsyQuestionnaireAnswer`记录
2. 获取题目 → 根据`paper_type`获取题目列表
3. 保存答案 → 保存到`PsyQuestionnaireAnswerDetail`
4. 提交问卷 → 自动计分 + 更新排名
### 3. 自动计分逻辑
```java
// 客观题计分
private BigDecimal calculateObjectiveScore(PsyQuestionnaireItem item, AnswerDetailVO answer) {
switch(item.getItemType()) {
case "radio":
// 单选:检查选项是否正确
return checkOptionCorrect(item, answer.getOptionId()) ? item.getScore() : BigDecimal.ZERO;
case "checkbox":
// 多选:检查所有选项是否正确
return calculateMultiChoiceScore(item, answer.getOptionIds());
case "boolean":
// 判断:检查选项是否正确
return checkOptionCorrect(item, answer.getOptionId()) ? item.getScore() : BigDecimal.ZERO;
case "input":
// 填空:文本匹配
return checkTextMatch(item, answer.getAnswerText()) ? item.getScore() : BigDecimal.ZERO;
// ... 其他类型
}
}
```
### 4. 排名计算
```sql
-- 更新排名
UPDATE psy_questionnaire_answer qa
SET qa.rank = (
SELECT COUNT(*) + 1
FROM psy_questionnaire_answer qa2
WHERE qa2.questionnaire_id = qa.questionnaire_id
AND (
qa2.total_score > qa.total_score
OR (qa2.total_score = qa.total_score AND qa2.submit_time < qa.submit_time)
)
)
WHERE qa.questionnaire_id = #{questionnaireId}
AND qa.status = '1'
```
---
## 📌 实施步骤
1.**创建问卷答案详情表**SQL
2.**修改量表列表查询,包含问卷**(后端)
3.**修改量表管理页面,显示问卷**(前端)
4.**创建问卷答题功能**(后端+前端)
5.**实现自动计分功能**(后端)
6.**实现主观题评分功能**(后端+前端)
7.**实现成绩排名功能**(后端+前端)
---
## ⚠️ 注意事项
1. 问卷和量表的数据结构不同,需要统一转换
2. 组卷方式(随机、手动、混合)需要在获取题目时实现
3. 主观题评分需要权限控制
4. 排名计算要考虑性能,可能需要定时任务
5. 填空题的文本匹配需要考虑容错性
---
**创建时间**: 2025-01-XX
**最后更新**: 2025-01-XX