xinli/心理测评问题修复说明.md
2025-12-02 15:12:55 +08:00

399 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 心理测评问题修复说明
## 修复日期
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`
**修改内容**:
1. **导入接口更改** (第300行)
```javascript
// 修改前
import { listProfile } from "@/api/psychology/profile";
// 修改后
import { listStudentProfile } from "@/api/psychology/profile";
```
2. **加载监区选项** (第556行)
```javascript
// 修改前
listProfile({ pageNum: 1, pageSize: 10000, status: undefined }).then(response => {
// 修改后
listStudentProfile({ pageNum: 1, pageSize: 10000 }).then(response => {
```
3. **获取用户选择列表** (第599行)
```javascript
// 修改前
return listProfile(query).then(response => {
// 修改后
return listStudentProfile(query).then(response => {
```
4. **批量获取所有用户** (第675行)
```javascript
// 修改前
const response = await listProfile({
// 修改后
const response = await listStudentProfile({
```
5. **保留查询参数配置** (第346-353行)
```javascript
userQueryParams: {
pageNum: 1,
pageSize: 10,
infoNumber: undefined,
userName: undefined,
prisonArea: undefined,
status: undefined // 不限制状态
}
```
**修复效果**:
- ✅ 量表权限管理和用户档案显示相同数量的用户都是3014
- ✅ 只显示学员角色的用户,数据更准确
- ✅ 数据统计保持一致性
---
### 问题2测评状态显示和管理 ✅
**问题描述**:
1. 用户退出测评后,状态显示为"进行中"而不是"已暂停"
2. 希望区分"进行中"(正在答题)、"已暂停"(退出或暂停)、"已完成"(提交完成)
3. 暂停和退出都要保留用户填写的内容
**状态定义**:
```
status = '0' - 进行中(正在答题,未退出)
status = '1' - 已完成(已提交)
status = '2' - 已作废(删除或作废)
status = '3' - 已暂停(用户暂停或退出)
```
**现有逻辑验证**:
#### ✅ 暂停功能
**前端** (`xinli-ui/src/views/psychology/assessment/taking.vue` 第494-503行):
```javascript
handlePause() {
this.$modal.confirm('确定要暂停测评吗?您可以稍后继续完成。').then(() => {
pauseAssessment(this.assessmentId).then(() => {
this.$modal.msgSuccess("测评已暂停");
// 跳转回列表页
this.$router.push(isStudent ? '/student/tests' : '/psychology/assessment');
});
});
}
```
**后端** (`PsyAssessmentMapper.xml` 第142-152行):
```xml
<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行):
```javascript
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行):
```javascript
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行):
```java
// 更新测评状态为已完成
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行):
```vue
<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行):
```xml
<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`):
```javascript
// 每次选择答案时自动保存
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行):
```vue
<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行):
```vue
<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验证
1. 登录系统
2. 进入"心理 → 用户档案",查看总数 → 应显示 **3014**(学员用户)
3. 进入"心理 → 量表权限管理",点击"分配用户"
4. 不添加任何筛选条件,查看用户列表总数 → 应显示 **3014**(与用户档案一致)
5. ✅ 数量一致,都显示学员角色用户
**说明**: 修改后两个页面都只显示拥有学员角色的用户3014个不再显示其他角色的用户如管理员等2个用户
#### 问题2验证
**测试场景1暂停测评**
1. 开始一个测评
2. 答几道题
3. 点击"暂停"按钮
4. 返回测评管理列表
5. ✅ 该测评显示为"已暂停"状态(黄色标签)
6. 点击"继续答题"
7. ✅ 之前答的题目答案都保留
**测试场景2退出测评**
1. 开始一个测评
2. 答几道题
3. 点击"退出"按钮
4. 返回测评管理列表
5. ✅ 该测评显示为"已暂停"状态(黄色标签)
6. 点击"继续答题"
7. ✅ 之前答的题目答案都保留
**测试场景3完成测评**
1. 开始一个测评
2. 答完所有题目
3. 点击"提交测评"
4. 返回测评管理列表
5. ✅ 该测评显示为"已完成"状态(绿色标签)
6. ✅ 不再显示"继续答题"按钮
7. ✅ 显示"查看答题"和"查看报告"按钮
## 技术说明
### 数据库表结构
```sql
-- 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测评状态管理 ✅
**验证结果**: 现有逻辑已正确实现
**核心功能**:
1. ✅ 退出测评会设置 status='3'(已暂停)
2. ✅ 暂停测评会设置 status='3'(已暂停)
3. ✅ 提交测评会设置 status='1'(已完成)
4. ✅ 继续答题会恢复 status='0'(进行中)
5. ✅ 所有答案都会自动保存,不会丢失
6. ✅ 测评列表正确显示各种状态
**如果用户仍然遇到"退出显示进行中"的问题,请检查**:
1. 浏览器缓存是否清除
2. 后端服务是否重启
3. 数据库中 psy_assessment 表的 status 字段值
4. 网络请求是否成功F12查看Network
5. 是否有其他地方修改了状态
## 部署说明
1. **前端部署**:
- 修改文件: `xinli-ui/src/views/psychology/permission/index.vue`
- 重新编译: `npm run build`
- 部署到服务器
2. **无需后端修改**:
- 后端逻辑已经正确实现
- 无需重新部署
3. **验证步骤**:
- 清除浏览器缓存
- 刷新页面
- 按照验证步骤测试
## 附录:常见问题
**Q: 为什么要查询所有状态的用户?**
A: 因为即使用户被停用或删除,其历史测评记录和权限仍然存在,需要能够管理和查看。
**Q: 状态'0'和'3'有什么区别?**
A:
- status='0'(进行中): 用户正在答题页面答题
- status='3'(已暂停): 用户点击了暂停或退出按钮,离开了答题页面
**Q: 如何区分正在答题和已退出?**
A:
- 在测评列表中status='0'和'3'都显示"继续答题"按钮
- 区别在于status='0'可能是打开了答题页面但没有答题status='3'是明确点击了暂停/退出
**Q: 答案什么时候保存?**
A: 每次选择答案后都会立即自动保存到数据库,不需要手动保存。