12 KiB
心理测评问题修复说明
修复日期
2025年12月1日
问题清单
问题1:用户档案与量表权限管理用户数量不一致 ✅
问题描述:
- 用户档案显示 3014 个用户
- 量表权限管理显示 3016 个用户
- 数据不一致导致分配权限时出现困惑
根本原因: 两个页面使用了不同的API接口:
- 用户档案页面:使用
listStudentProfile接口(/psychology/profile/student/list)- 只查询拥有学员角色的用户 → 3014个
- 量表权限管理:使用
listProfile接口(/psychology/profile/list)- 查询所有用户档案 → 3016个(包括非学员用户)
修复方案:
修改量表权限管理的用户查询逻辑,统一使用 listStudentProfile 接口,只查询学员用户,与用户档案页面保持一致。
修改文件:
xinli-ui/src/views/psychology/permission/index.vue
修改内容:
- 导入接口更改 (第300行)
// 修改前
import { listProfile } from "@/api/psychology/profile";
// 修改后
import { listStudentProfile } from "@/api/psychology/profile";
- 加载监区选项 (第556行)
// 修改前
listProfile({ pageNum: 1, pageSize: 10000, status: undefined }).then(response => {
// 修改后
listStudentProfile({ pageNum: 1, pageSize: 10000 }).then(response => {
- 获取用户选择列表 (第599行)
// 修改前
return listProfile(query).then(response => {
// 修改后
return listStudentProfile(query).then(response => {
- 批量获取所有用户 (第675行)
// 修改前
const response = await listProfile({
// 修改后
const response = await listStudentProfile({
- 保留查询参数配置 (第346-353行)
userQueryParams: {
pageNum: 1,
pageSize: 10,
infoNumber: undefined,
userName: undefined,
prisonArea: undefined,
status: undefined // 不限制状态
}
修复效果:
- ✅ 量表权限管理和用户档案显示相同数量的用户(都是3014)
- ✅ 只显示学员角色的用户,数据更准确
- ✅ 数据统计保持一致性
问题2:测评状态显示和管理 ✅
问题描述:
- 用户退出测评后,状态显示为"进行中"而不是"已暂停"
- 希望区分"进行中"(正在答题)、"已暂停"(退出或暂停)、"已完成"(提交完成)
- 暂停和退出都要保留用户填写的内容
状态定义:
status = '0' - 进行中(正在答题,未退出)
status = '1' - 已完成(已提交)
status = '2' - 已作废(删除或作废)
status = '3' - 已暂停(用户暂停或退出)
现有逻辑验证:
✅ 暂停功能
前端 (xinli-ui/src/views/psychology/assessment/taking.vue 第494-503行):
handlePause() {
this.$modal.confirm('确定要暂停测评吗?您可以稍后继续完成。').then(() => {
pauseAssessment(this.assessmentId).then(() => {
this.$modal.msgSuccess("测评已暂停");
// 跳转回列表页
this.$router.push(isStudent ? '/student/tests' : '/psychology/assessment');
});
});
}
后端 (PsyAssessmentMapper.xml 第142-152行):
<update id="pauseAssessment">
update psy_assessment
<set>
pause_time = sysdate(),
pause_count = pause_count + 1,
status = '3', <!-- 设置为已暂停 -->
update_time = sysdate()
</set>
where assessment_id = #{assessmentId}
</update>
✅ 退出功能
前端 (xinli-ui/src/views/psychology/assessment/taking.vue 第506-528行):
handleExit() {
this.$modal.confirm('确定要退出测评吗?已答题目将会保存。').then(() => {
this.loading = true;
// 先等待一小段时间,确保最后的答案保存请求发出
setTimeout(() => {
// 退出前先暂停测评,保存进度
pauseAssessment(this.assessmentId).then(() => { // ✅ 调用暂停接口
this.loading = false;
this.$modal.msgSuccess("测评进度已保存");
// 跳转回列表页
this.$router.push(isStudent ? '/student/tests' : '/psychology/assessment');
});
}, 500); // 等待500ms,确保答案保存请求已发送
});
}
说明: 退出功能也调用 pauseAssessment,会将状态设为 '3'(已暂停)
✅ 提交功能
前端 (xinli-ui/src/views/psychology/assessment/taking.vue 第531-560行):
handleSubmit() {
if (!this.isComplete) {
const remaining = this.itemList.length - this.answeredCount;
this.$modal.msgError(`还有 ${remaining} 道题未作答,请完成后再提交`);
return;
}
this.$modal.confirm('确定要提交测评吗?提交后将不能修改。').then(() => {
this.loading = true;
submitAssessment(this.assessmentId).then(response => {
this.loading = false;
this.$modal.msgSuccess("测评已提交,报告正在生成中...");
// 跳转到报告页面
});
});
}
后端 (PsyAssessmentController.java 第436-445行):
// 更新测评状态为已完成
assessment.setStatus("1"); // ✅ 设置为已完成
assessment.setSubmitTime(new Date());
if (assessment.getStartTime() != null) {
long completeSeconds = (System.currentTimeMillis() - assessment.getStartTime().getTime()) / 1000;
assessment.setCompleteTime((int) completeSeconds);
}
assessmentService.updateAssessment(assessment);
✅ 继续答题功能
前端 (xinli-ui/src/views/psychology/assessment/index.vue 第103-106行):
<el-button
@click="handleContinue(scope.row)"
v-if="scope.row.status === '0' || scope.row.status === '3'"
>继续答题</el-button>
说明: 只有"进行中"(status='0')或"已暂停"(status='3')状态才显示"继续答题"按钮
✅ 恢复测评
后端 (PsyAssessmentMapper.xml 第154-163行):
<update id="resumeAssessment">
update psy_assessment
<set>
resume_time = sysdate(),
status = '0', <!-- 恢复为进行中 -->
update_time = sysdate()
</set>
where assessment_id = #{assessmentId}
</update>
说明: 点击"继续答题"时会调用 resumeAssessment,将状态从 '3' 改为 '0'
✅ 答案自动保存
前端 (xinli-ui/src/views/psychology/assessment/taking.vue):
// 每次选择答案时自动保存
handleAnswerChange() {
// ... 保存逻辑
this.saveCurrentAnswer();
}
说明:
- 用户每选择一个答案都会自动保存到数据库
- 退出或暂停时不会丢失已答题目
- 继续答题时可以从上次位置继续
测评状态流转图
开始测评 ──> status='0'(进行中)
│
├──> 点击"暂停" ──> status='3'(已暂停)──> 点击"继续答题" ──> status='0'
│
├──> 点击"退出" ──> status='3'(已暂停)──> 点击"继续答题" ──> status='0'
│
└──> 点击"提交" ──> status='1'(已完成)
测评管理列表显示
文件: xinli-ui/src/views/psychology/assessment/index.vue
状态显示 (第81-87行):
<el-table-column label="状态" align="center" prop="status" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '0'" type="info">进行中</el-tag>
<el-tag v-else-if="scope.row.status === '1'" type="success">已完成</el-tag>
<el-tag v-else-if="scope.row.status === '2'" type="danger">已作废</el-tag>
<el-tag v-else-if="scope.row.status === '3'" type="warning">已暂停</el-tag>
</template>
</el-table-column>
状态筛选 (第22-28行):
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="状态" clearable>
<el-option label="进行中" value="0" />
<el-option label="已完成" value="1" />
<el-option label="已作废" value="2" />
<el-option label="已暂停" value="3" />
</el-select>
</el-form-item>
修复验证
验证步骤
问题1验证:
- 登录系统
- 进入"心理 → 用户档案",查看总数 → 应显示 3014(学员用户)
- 进入"心理 → 量表权限管理",点击"分配用户"
- 不添加任何筛选条件,查看用户列表总数 → 应显示 3014(与用户档案一致)
- ✅ 数量一致,都显示学员角色用户
说明: 修改后,两个页面都只显示拥有学员角色的用户(3014个),不再显示其他角色的用户(如管理员等2个用户)。
问题2验证:
测试场景1:暂停测评
- 开始一个测评
- 答几道题
- 点击"暂停"按钮
- 返回测评管理列表
- ✅ 该测评显示为"已暂停"状态(黄色标签)
- 点击"继续答题"
- ✅ 之前答的题目答案都保留
测试场景2:退出测评
- 开始一个测评
- 答几道题
- 点击"退出"按钮
- 返回测评管理列表
- ✅ 该测评显示为"已暂停"状态(黄色标签)
- 点击"继续答题"
- ✅ 之前答的题目答案都保留
测试场景3:完成测评
- 开始一个测评
- 答完所有题目
- 点击"提交测评"
- 返回测评管理列表
- ✅ 该测评显示为"已完成"状态(绿色标签)
- ✅ 不再显示"继续答题"按钮
- ✅ 显示"查看答题"和"查看报告"按钮
技术说明
数据库表结构
-- psy_assessment 测评表
CREATE TABLE psy_assessment (
assessment_id BIGINT PRIMARY KEY,
scale_id BIGINT,
assessee_name VARCHAR(100),
status CHAR(1), -- 0:进行中 1:已完成 2:已作废 3:已暂停
start_time DATETIME,
pause_time DATETIME,
resume_time DATETIME,
submit_time DATETIME,
pause_count INT DEFAULT 0,
complete_time INT,
total_score DECIMAL(10,2),
-- ... 其他字段
);
API接口
POST /psychology/assessment/pause/{assessmentId}- 暂停测评POST /psychology/assessment/resume/{assessmentId}- 恢复测评POST /psychology/assessment/submit/{assessmentId}- 提交测评POST /psychology/assessment/answer/save- 保存答案
总结
问题1:用户数量不一致 ✅
修复方式: 统一使用学员档案接口(listStudentProfile),只查询学员角色用户
影响范围: 量表权限管理的用户选择对话框
预期效果:
- 用户档案和量表权限管理显示相同数量的用户(都是3014)
- 只显示学员用户,不包括其他角色的用户
- 数据来源统一,避免混淆
问题2:测评状态管理 ✅
验证结果: 现有逻辑已正确实现
核心功能:
- ✅ 退出测评会设置 status='3'(已暂停)
- ✅ 暂停测评会设置 status='3'(已暂停)
- ✅ 提交测评会设置 status='1'(已完成)
- ✅ 继续答题会恢复 status='0'(进行中)
- ✅ 所有答案都会自动保存,不会丢失
- ✅ 测评列表正确显示各种状态
如果用户仍然遇到"退出显示进行中"的问题,请检查:
- 浏览器缓存是否清除
- 后端服务是否重启
- 数据库中 psy_assessment 表的 status 字段值
- 网络请求是否成功(F12查看Network)
- 是否有其他地方修改了状态
部署说明
-
前端部署:
- 修改文件:
xinli-ui/src/views/psychology/permission/index.vue - 重新编译:
npm run build - 部署到服务器
- 修改文件:
-
无需后端修改:
- 后端逻辑已经正确实现
- 无需重新部署
-
验证步骤:
- 清除浏览器缓存
- 刷新页面
- 按照验证步骤测试
附录:常见问题
Q: 为什么要查询所有状态的用户? A: 因为即使用户被停用或删除,其历史测评记录和权限仍然存在,需要能够管理和查看。
Q: 状态'0'和'3'有什么区别? A:
- status='0'(进行中): 用户正在答题页面答题
- status='3'(已暂停): 用户点击了暂停或退出按钮,离开了答题页面
Q: 如何区分正在答题和已退出? A:
- 在测评列表中,status='0'和'3'都显示"继续答题"按钮
- 区别在于:status='0'可能是打开了答题页面但没有答题,status='3'是明确点击了暂停/退出
Q: 答案什么时候保存? A: 每次选择答案后都会立即自动保存到数据库,不需要手动保存。