用户档案、大模型bug修改

This commit is contained in:
xiao12feng 2025-12-02 17:09:22 +08:00
parent 2931e0e1c0
commit 5456739b22
16 changed files with 341 additions and 94 deletions

View File

@ -186,6 +186,7 @@ public class PsyAssessmentController extends BaseController
/**
* 开始测评
* 允许管理员和学员访问
* 每个用户对同一量表只能有一条未完成的测评记录
*/
@PostMapping("/start")
public AjaxResult start(@Validated @RequestBody AssessmentStartVO startVO)
@ -200,35 +201,53 @@ public class PsyAssessmentController extends BaseController
currentUsername = SecurityUtils.getUsername();
} catch (Exception e) {
logger.warn("获取用户信息失败,可能是匿名访问: {}", e.getMessage());
// 如果是匿名访问userId username 可以为 null
}
// 确定实际的测评用户ID
// 如果传入了targetUserId管理员代替用户测评使用targetUserId
// 否则使用当前登录用户ID
Long assessmentUserId = startVO.getTargetUserId() != null ? startVO.getTargetUserId() : currentUserId;
// 检查是否已存在该用户对该量表的未完成测评记录
if (assessmentUserId != null && startVO.getScaleId() != null)
{
// 使用不过滤的查询方法获取所有测评记录
List<PsyAssessment> existingList = assessmentService.selectAssessmentByUserAndScale(assessmentUserId, startVO.getScaleId());
// 查找未完成的测评状态为进行中或已暂停
for (PsyAssessment existing : existingList)
{
if ("0".equals(existing.getStatus()) || "3".equals(existing.getStatus()))
{
// 已存在未完成的测评直接返回该测评ID
// 不在这里改变状态让前端在进入答题页面后调用 resume API
logger.info("复用已存在的测评记录 - assessmentId: {}, status: {}",
existing.getAssessmentId(), existing.getStatus());
return success(existing.getAssessmentId());
}
}
}
// 没有未完成的测评创建新的测评记录
// 初始状态为"已暂停"等用户真正进入答题页面后再改为"进行中"
PsyAssessment assessment = new PsyAssessment();
assessment.setScaleId(startVO.getScaleId());
assessment.setAssesseeName(startVO.getAssesseeName());
assessment.setAssesseeGender(startVO.getAssesseeGender());
assessment.setAssesseeAge(startVO.getAssesseeAge());
assessment.setAssesseePhone(startVO.getAssesseePhone());
assessment.setStatus("0");
assessment.setStatus("3"); // 初始状态为"已暂停"
assessment.setStartTime(new Date());
assessment.setIpAddress(IpUtils.getIpAddr());
assessment.setUserAgent(ServletUtils.getRequest().getHeader("User-Agent"));
// 设置用户ID优先使用targetUserId
if (assessmentUserId != null) {
assessment.setUserId(assessmentUserId);
}
// 设置创建者记录是谁创建的测评
if (currentUsername != null && !currentUsername.isEmpty()) {
assessment.setCreateBy(currentUsername);
} else {
assessment.setCreateBy("system"); // 默认值
assessment.setCreateBy("system");
}
logger.info("创建测评 - scaleId: {}, targetUserId: {}, assessmentUserId: {}, currentUserId: {}, assesseeName: {}",
@ -252,6 +271,53 @@ public class PsyAssessmentController extends BaseController
}
}
/**
* 重置测评删除未完成的测评记录重新开始
* 允许管理员和学员访问学员只能重置自己的测评
*/
@PostMapping("/reset")
public AjaxResult reset(@RequestBody AssessmentStartVO startVO)
{
try {
Long currentUserId = SecurityUtils.getUserId();
Long assessmentUserId = startVO.getTargetUserId() != null ? startVO.getTargetUserId() : currentUserId;
if (assessmentUserId == null || startVO.getScaleId() == null)
{
return error("参数不完整");
}
// 检查权限学员只能重置自己的测评
boolean hasManagePerm = false;
try {
hasManagePerm = SecurityUtils.hasPermi("psychology:assessment:edit");
} catch (Exception ignored) {}
if (!hasManagePerm && !assessmentUserId.equals(currentUserId)) {
return error("无权重置其他用户的测评");
}
// 查找该用户对该量表的所有测评记录
List<PsyAssessment> existingList = assessmentService.selectAssessmentByUserAndScale(assessmentUserId, startVO.getScaleId());
// 删除所有未完成的测评
for (PsyAssessment existing : existingList)
{
if ("0".equals(existing.getStatus()) || "3".equals(existing.getStatus()))
{
assessmentService.deleteAssessmentByIds(new Long[]{existing.getAssessmentId()});
logger.info("删除未完成的测评记录 - assessmentId: {}", existing.getAssessmentId());
}
}
// 创建新的测评记录
return start(startVO);
} catch (Exception e) {
logger.error("重置测评异常", e);
return error("重置测评失败:" + e.getMessage());
}
}
/**
* 修改测评
*/

View File

@ -49,6 +49,15 @@ public interface PsyAssessmentMapper
*/
public List<PsyAssessment> selectPausedAssessmentList(Long userId);
/**
* 查询用户对某个量表的所有测评记录不过滤用于内部逻辑
*
* @param userId 用户ID
* @param scaleId 量表ID
* @return 测评集合
*/
public List<PsyAssessment> selectAssessmentByUserAndScale(@Param("userId") Long userId, @Param("scaleId") Long scaleId);
/**
* 新增测评
*

View File

@ -85,6 +85,12 @@ public class PsyAssessmentServiceImpl implements IPsyAssessmentService
return assessmentMapper.selectPausedAssessmentList(userId);
}
@Override
public List<PsyAssessment> selectAssessmentByUserAndScale(Long userId, Long scaleId)
{
return assessmentMapper.selectAssessmentByUserAndScale(userId, scaleId);
}
@Override
public int insertAssessment(PsyAssessment assessment)
{

View File

@ -141,16 +141,10 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService
profile.setInfoNumber(infoNumber);
validateInfoNumberUnique(infoNumber, null);
// 验证姓名如果提供只能包含汉字和数字
// 处理姓名去除首尾空格
if (StringUtils.isNotEmpty(profile.getUserName()))
{
String userName = profile.getUserName().trim();
if (!userName.matches("^[\\u4e00-\\u9fa5\\d]+$"))
{
log.error("创建用户档案失败姓名格式错误只能输入汉字和数字userName: {}", userName);
throw new ServiceException("姓名只能输入汉字和数字");
}
profile.setUserName(userName);
profile.setUserName(profile.getUserName().trim());
}
Long userId = profile.getUserId();
@ -311,15 +305,10 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService
profile.setInfoNumber(infoNumber);
validateInfoNumberUnique(infoNumber, profile.getProfileId());
// 验证姓名如果提供只能包含汉字和数字
// 处理姓名去除首尾空格并同步到用户表
if (StringUtils.isNotEmpty(profile.getUserName()))
{
String userName = profile.getUserName().trim();
if (!userName.matches("^[\\u4e00-\\u9fa5\\d]+$"))
{
log.error("修改用户档案失败姓名格式错误只能输入汉字和数字userName: {}", userName);
throw new ServiceException("姓名只能输入汉字和数字");
}
profile.setUserName(userName);
syncUserName(profile.getUserId(), userName);
}

View File

@ -48,6 +48,15 @@ public interface IPsyAssessmentService
*/
public List<PsyAssessment> selectPausedAssessmentList(Long userId);
/**
* 查询用户对某个量表的所有测评记录不过滤用于内部逻辑
*
* @param userId 用户ID
* @param scaleId 量表ID
* @return 测评集合
*/
public List<PsyAssessment> selectAssessmentByUserAndScale(Long userId, Long scaleId);
/**
* 新增测评
*

View File

@ -34,7 +34,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectAssessmentVo">
select a.assessment_id, a.scale_id, s.scale_name, a.user_id, a.assessee_name, a.assessee_gender, a.assessee_age,
select a.assessment_id, a.scale_id, s.scale_name, a.user_id,
COALESCE(u.nick_name, a.assessee_name) as assessee_name,
a.assessee_gender, a.assessee_age,
a.assessee_id_card, a.assessee_phone, a.assessee_email, a.start_time, a.pause_time,
a.resume_time, a.pause_count, a.submit_time, a.complete_time, a.total_score, a.status,
a.ip_address, a.user_agent,
@ -43,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from psy_assessment a
left join psy_scale s on a.scale_id = s.scale_id
left join psy_assessment_report r on a.assessment_id = r.assessment_id
left join sys_user u on a.user_id = u.user_id
</sql>
<select id="selectAssessmentById" parameterType="Long" resultMap="PsyAssessmentResult">
@ -53,6 +56,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectAssessmentList" parameterType="com.ddnai.system.domain.psychology.PsyAssessment" resultMap="PsyAssessmentResult">
<include refid="selectAssessmentVo"/>
<where>
<!-- 只显示每个用户对每个量表的最新记录 -->
a.assessment_id IN (
SELECT MAX(t.assessment_id)
FROM psy_assessment t
GROUP BY t.user_id, t.scale_id
)
<if test="scaleId != null">
AND a.scale_id = #{scaleId}
</if>
@ -66,13 +75,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND a.status = #{status}
</if>
</where>
order by a.create_time desc
order by a.start_time desc
</select>
<select id="selectAssessmentListByUserId" parameterType="Long" resultMap="PsyAssessmentResult">
<include refid="selectAssessmentVo"/>
where a.user_id = #{userId}
order by a.create_time desc
<!-- 只显示每个量表的最新记录 -->
AND a.assessment_id IN (
SELECT MAX(t.assessment_id)
FROM psy_assessment t
WHERE t.user_id = #{userId}
GROUP BY t.scale_id
)
order by a.start_time desc
</select>
<select id="selectPausedAssessmentList" parameterType="Long" resultMap="PsyAssessmentResult">
@ -86,6 +102,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by a.pause_time desc
</select>
<!-- 查询用户对某个量表的所有测评记录(不过滤,用于内部逻辑) -->
<select id="selectAssessmentByUserAndScale" resultMap="PsyAssessmentResult">
<include refid="selectAssessmentVo"/>
where a.user_id = #{userId} and a.scale_id = #{scaleId}
order by a.assessment_id desc
</select>
<insert id="insertAssessment" parameterType="com.ddnai.system.domain.psychology.PsyAssessment" useGeneratedKeys="true" keyProperty="assessmentId">
insert into psy_assessment (
<if test="scaleId != null">scale_id, </if>
@ -130,6 +153,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assesseeGender != null">assessee_gender = #{assesseeGender}, </if>
<if test="assesseeAge != null">assessee_age = #{assesseeAge}, </if>
<if test="totalScore != null">total_score = #{totalScore}, </if>
<if test="startTime != null">start_time = #{startTime}, </if>
<if test="submitTime != null">submit_time = #{submitTime}, </if>
<if test="completeTime != null">complete_time = #{completeTime}, </if>
<if test="status != null">status = #{status}, </if>
@ -155,6 +179,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update psy_assessment
<set>
resume_time = sysdate(),
start_time = sysdate(),
status = '0',
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate()

View File

@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
p.prison, p.prison_area, p.gender, p.nation, p.education_level, p.crime_name,
p.sentence_term, p.sentence_start_date, p.sentence_end_date, p.entry_date,
p.info_number, p.create_by, p.create_time, p.update_by, p.update_time, p.remark,
u.user_name, u.phonenumber as phone, u.nick_name, u.email, u.sex, u.status, u.dept_id, u.create_time as user_create_time
u.nick_name as user_name, u.phonenumber as phone, u.nick_name, u.email, u.sex, u.status, u.dept_id, u.create_time as user_create_time
</sql>
<select id="selectProfileById" parameterType="Long" resultMap="PsyUserProfileResult">
@ -69,7 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 查询用户档案列表,从 sys_user 开始LEFT JOIN psy_user_profile与系统用户管理查询一致 -->
<select id="selectProfileList" parameterType="com.ddnai.system.domain.psychology.PsyUserProfile" resultMap="PsyUserProfileResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
select u.user_id, u.dept_id, u.nick_name, u.nick_name as user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
d.dept_name, d.leader,
p.profile_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
p.prison, p.prison_area, p.gender, p.nation, p.education_level, p.crime_name,
@ -83,7 +83,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND u.user_id = #{userId}
</if>
<if test="userName != null and userName != ''">
AND u.user_name like concat('%', #{userName}, '%')
AND u.nick_name like concat('%', #{userName}, '%')
</if>
<if test="profileType != null and profileType != ''">
AND p.profile_type = #{profileType}
@ -215,7 +215,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 查询学员用户档案列表:只返回拥有学员角色的用户 -->
<select id="selectStudentProfileList" parameterType="com.ddnai.system.domain.psychology.PsyUserProfile" resultMap="PsyUserProfileResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
select u.user_id, u.dept_id, u.nick_name, u.nick_name as user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
d.dept_name, d.leader,
p.profile_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
p.prison, p.prison_area, p.gender, p.nation, p.education_level, p.crime_name,
@ -236,7 +236,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND u.user_id = #{userId}
</if>
<if test="userName != null and userName != ''">
AND u.user_name like concat('%', #{userName}, '%')
AND u.nick_name like concat('%', #{userName}, '%')
</if>
<if test="profileType != null and profileType != ''">
AND p.profile_type = #{profileType}

View File

@ -63,7 +63,10 @@ export function saveAnswer(data) {
return request({
url: '/psychology/assessment/answer',
method: 'post',
data: data
data: data,
headers: {
repeatSubmit: false // 跳过防重复提交检查,允许快速保存答案
}
})
}
@ -71,7 +74,10 @@ export function saveAnswer(data) {
export function pauseAssessment(assessmentId) {
return request({
url: '/psychology/assessment/pause/' + assessmentId,
method: 'post'
method: 'post',
headers: {
repeatSubmit: false // 跳过防重复提交检查
}
})
}
@ -79,7 +85,10 @@ export function pauseAssessment(assessmentId) {
export function resumeAssessment(assessmentId) {
return request({
url: '/psychology/assessment/resume/' + assessmentId,
method: 'post'
method: 'post',
headers: {
repeatSubmit: false // 跳过防重复提交检查
}
})
}
@ -145,3 +154,12 @@ export function getScaleDeptStats(data) {
})
}
// 重置测评(删除未完成的测评记录,重新开始)
export function resetAssessment(data) {
return request({
url: '/psychology/assessment/reset',
method: 'post',
data: data
})
}

View File

@ -104,6 +104,15 @@
v-if="scope.row.status === '0' || scope.row.status === '3'"
v-hasPermi="['psychology:assessment:edit']"
>继续答题</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-refresh"
style="color: #E6A23C;"
@click="handleReset(scope.row)"
v-if="scope.row.status === '0' || scope.row.status === '3'"
v-hasPermi="['psychology:assessment:edit']"
>重新开始</el-button>
<el-button
size="mini"
type="text"
@ -190,7 +199,7 @@
</template>
<script>
import { listAssessment, getAssessment, delAssessment, pausedAssessmentList, getAssessmentAnswers, getAssessmentItems } from "@/api/psychology/assessment";
import { listAssessment, getAssessment, delAssessment, pausedAssessmentList, getAssessmentAnswers, getAssessmentItems, resetAssessment } from "@/api/psychology/assessment";
import { listScale } from "@/api/psychology/scale";
import { listOption } from "@/api/psychology/option";
@ -317,6 +326,31 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 重置测评(删除当前记录,重新开始) */
handleReset(row) {
this.$modal.confirm('确定要重新开始测评吗?当前的答题记录将被清除。').then(() => {
const resetData = {
scaleId: row.scaleId,
targetUserId: row.userId,
assesseeName: row.assesseeName,
assesseeGender: row.assesseeGender || '0',
assesseeAge: row.assesseeAge || 0,
assesseePhone: row.assesseePhone,
anonymous: false
};
resetAssessment(resetData).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess("测评已重置");
const assessmentId = response.data;
this.$router.push({ path: '/psychology/assessment/taking', query: { assessmentId: assessmentId } });
}
}).catch(error => {
console.error('重置测评失败:', error);
this.$modal.msgError("重置测评失败,请重试");
});
});
},
/** 查看答题详情 */
handleViewAnswers(row) {
this.currentAssessment = row;

View File

@ -67,7 +67,7 @@
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150">
<el-table-column label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button
size="mini"
@ -75,6 +75,13 @@
icon="el-icon-edit-outline"
@click="handleContinue(scope.row)"
>继续测评</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-refresh"
style="color: #E6A23C;"
@click="handleReset(scope.row)"
>重新开始</el-button>
</template>
</el-table-column>
</el-table>
@ -83,7 +90,7 @@
</template>
<script>
import { startAssessment, pausedAssessmentList, resumeAssessment } from "@/api/psychology/assessment";
import { startAssessment, pausedAssessmentList, resumeAssessment, resetAssessment } from "@/api/psychology/assessment";
import { listScale } from "@/api/psychology/scale";
import { listStudentProfile } from "@/api/psychology/profile";
@ -459,6 +466,36 @@ export default {
this.$router.push({ path: '/psychology/assessment/taking', query: { assessmentId: row.assessmentId } });
}
},
/** 重置测评(删除当前记录,重新开始) */
handleReset(row) {
this.$modal.confirm('确定要重新开始测评吗?当前的答题记录将被清除。').then(() => {
this.loading = true;
//
const profile = this.profileList.find(p => p.userId === row.userId);
const resetData = {
scaleId: row.scaleId,
targetUserId: row.userId,
assesseeName: profile ? profile.userName : row.assesseeName,
assesseeGender: '0',
assesseeAge: 0,
assesseePhone: profile ? profile.phone : null,
anonymous: false
};
resetAssessment(resetData).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess("测评已重置");
const assessmentId = response.data;
this.$router.push({ path: '/psychology/assessment/taking', query: { assessmentId: assessmentId } });
}
this.loading = false;
}).catch(error => {
console.error('重置测评失败:', error);
this.$modal.msgError("重置测评失败,请重试");
this.loading = false;
});
});
},
/** 返回 */
handleBack() {
this.$router.push('assessment');

View File

@ -67,7 +67,7 @@
v-for="option in currentOptions"
:key="option.optionId"
class="option-item"
@click="selectedOption = option.optionId"
@click="selectSingleOption(option.optionId)"
>
<el-radio :label="option.optionId">{{ option.optionCode }}. {{ option.optionContent }}</el-radio>
<el-button
@ -139,7 +139,7 @@
</template>
<script>
import { getAssessment, pauseAssessment, getAssessmentItems, submitAssessment, getAssessmentAnswers } from "@/api/psychology/assessment";
import { getAssessment, pauseAssessment, resumeAssessment, getAssessmentItems, submitAssessment, getAssessmentAnswers } from "@/api/psychology/assessment";
import { listOption } from "@/api/psychology/option";
import { saveAnswer } from "@/api/psychology/assessment";
import voiceIcon from '@/assets/images/voice.png';
@ -158,6 +158,7 @@ export default {
answersMap: {},
loading: false,
saveTimer: null, //
hasResumed: false, // resume API
// TTS
isTtsSupported: false,
useAndroidTts: false,
@ -184,13 +185,15 @@ export default {
answeredCount() {
//
return this.itemList.filter(item => {
const answer = this.answersMap[item.itemId];
// 使 key
const itemIdStr = String(item.itemId);
const answer = this.answersMap[item.itemId] || this.answersMap[itemIdStr];
if (!answer) {
return false;
}
// optionId optionIds
if (item.itemType === 'single') {
return answer.optionId != null;
if (item.itemType === 'single' || item.itemType === 'matrix') {
return answer.optionId != null && answer.optionId !== '';
} else if (item.itemType === 'multiple') {
return answer.optionIds != null && answer.optionIds.trim().length > 0;
}
@ -409,20 +412,36 @@ export default {
//
const savedAnswers = answersRes.data || [];
console.log('从服务器加载的答案数量:', savedAnswers.length);
savedAnswers.forEach(answer => {
this.answersMap[answer.itemId] = {
// 使 $set 使 itemId key
const itemIdKey = answer.itemId;
this.$set(this.answersMap, itemIdKey, {
assessmentId: answer.assessmentId,
itemId: answer.itemId,
optionId: answer.optionId,
optionIds: answer.optionIds,
answerScore: answer.answerScore
};
});
});
console.log('加载后的 answersMap:', JSON.stringify(this.answersMap));
//
this.loadAllOptions().then(() => {
//
this.loadCurrentAnswer();
// resume API ""
//
if (!this.hasResumed) {
this.hasResumed = true;
resumeAssessment(this.assessmentId).then(() => {
console.log('测评状态已更新为进行中');
}).catch(error => {
console.warn('更新测评状态失败:', error);
//
});
}
}).catch(error => {
console.error('加载选项失败:', error);
this.$modal.msgError("加载题目选项失败,请刷新重试");
@ -454,14 +473,14 @@ export default {
handleAnswerChange() {
const itemId = this.currentItem.itemId;
const answer = {
assessmentId: this.assessmentId,
itemId: itemId,
assessmentId: parseInt(this.assessmentId),
itemId: parseInt(itemId),
optionId: null,
optionIds: null,
answerScore: 0
};
if (this.currentItem.itemType === 'single') {
if (this.currentItem.itemType === 'single' || this.currentItem.itemType === 'matrix') {
answer.optionId = this.selectedOption;
//
const selectedOpt = this.currentOptions.find(opt => opt.optionId === this.selectedOption);
@ -470,6 +489,7 @@ export default {
}
// 使 $set
this.$set(this.answersMap, itemId, answer);
console.log('单选题答案已保存到本地 - itemId:', itemId, 'optionId:', answer.optionId, 'answersMap:', JSON.stringify(this.answersMap));
} else if (this.currentItem.itemType === 'multiple') {
answer.optionIds = this.selectedOptions.length > 0 ? this.selectedOptions.join(',') : null;
//
@ -483,6 +503,7 @@ export default {
answer.answerScore = totalScore;
// 使 $set
this.$set(this.answersMap, itemId, answer);
console.log('多选题答案已保存到本地 - itemId:', itemId, 'optionIds:', answer.optionIds);
}
//
@ -501,11 +522,13 @@ export default {
saveAnswerToServer(answer) {
//
if (!answer.optionId && !answer.optionIds) {
console.log('答案无效,跳过保存 - optionId:', answer.optionId, 'optionIds:', answer.optionIds);
return; //
}
saveAnswer(answer).then(() => {
//
console.log('正在保存答案到服务器:', JSON.stringify(answer));
saveAnswer(answer).then((response) => {
console.log('答案保存成功:', response);
}).catch(error => {
console.error('保存答案失败:', error);
//
@ -529,6 +552,14 @@ export default {
this.loadCurrentAnswer();
}
},
/** 选择单选选项 */
selectSingleOption(optionId) {
//
if (this.selectedOption !== optionId) {
this.selectedOption = optionId;
this.handleAnswerChange();
}
},
/** 切换多选选项 */
toggleMultipleOption(optionId) {
const index = this.selectedOptions.indexOf(optionId);
@ -537,6 +568,8 @@ export default {
} else {
this.selectedOptions.push(optionId);
}
//
this.handleAnswerChange();
},
/** 加载当前题目的答案 */
loadCurrentAnswer() {
@ -544,10 +577,13 @@ export default {
return;
}
const itemId = this.currentItem.itemId;
const answer = this.answersMap[itemId];
// key
const answer = this.answersMap[itemId] || this.answersMap[String(itemId)];
if (this.currentItem.itemType === 'single') {
this.selectedOption = answer && answer.optionId ? answer.optionId : null;
console.log('加载题目答案 - itemId:', itemId, 'itemType:', this.currentItem.itemType, 'answer:', answer);
if (this.currentItem.itemType === 'single' || this.currentItem.itemType === 'matrix') {
this.selectedOption = answer && answer.optionId != null ? answer.optionId : null;
this.selectedOptions = [];
} else if (this.currentItem.itemType === 'multiple') {
this.selectedOption = null;
@ -795,6 +831,7 @@ export default {
this.answersMap = {};
this.loading = false;
this.isTtsSupported = false;
this.hasResumed = false; // resume
if (this.saveTimer) {
clearTimeout(this.saveTimer);
this.saveTimer = null;

View File

@ -213,8 +213,7 @@
<el-form-item label="罪犯姓名" prop="userName">
<el-input
v-model="form.userName"
placeholder="请输入姓名(仅汉字)"
@input="handleUserNameInput"
placeholder="请输入姓名"
maxlength="50"
/>
</el-form-item>
@ -549,8 +548,7 @@ export default {
{ pattern: /^\d+$/, message: "信息编号只能输入数字", trigger: "blur" }
],
userName: [
{ required: true, message: "罪犯姓名不能为空", trigger: "blur" },
{ pattern: /^[\u4e00-\u9fa5\d]+$/, message: "姓名只能输入汉字和数字", trigger: "blur" }
{ required: true, message: "罪犯姓名不能为空", trigger: "blur" }
],
prisonArea: [
{ required: true, message: "监区不能为空", trigger: "blur" }
@ -718,11 +716,7 @@ export default {
const numericValue = value.replace(/\D/g, '')
this.form.infoNumber = numericValue
},
//
handleUserNameInput(value) {
//
this.form.userName = value.replace(/[^\u4e00-\u9fa5\d]/g, '')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1

View File

@ -151,15 +151,15 @@ export default {
generating: false,
reportDialogVisible: false,
comprehensiveReport: '',
// ========== Ollama ==========
API_URL: 'http://192.168.0.106:11434/api/chat',
API_KEY: '', // API Key
MODEL: 'deepseek-r1:32b',
// ========== Kimi API ==========
API_URL: 'https://api.moonshot.cn/v1/chat/completions',
API_KEY: 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m',
MODEL: 'moonshot-v1-32k',
// ========== Kimi API==========
// API_URL: 'https://api.moonshot.cn/v1/chat/completions',
// API_KEY: 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m',
// MODEL: 'moonshot-v1-32k'
// ========== Ollama==========
// API_URL: 'http://192.168.0.106:11434/api/chat',
// API_KEY: '', // API Key
// MODEL: 'deepseek-r1:32b'
}
},
created() {

View File

@ -403,14 +403,14 @@ export default {
this.aiError = '';
this.aiResult = '';
// Ollama
const API_URL = 'http://192.168.0.106:11434/api/chat';
const API_KEY = ''; // API Key
const MODEL = 'deepseek-r1:32b';
// Kimi API
// const API_URL = 'https://api.moonshot.cn/v1/chat/completions';
// const API_KEY = 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m';
// const MODEL = 'moonshot-v1-32k';
// Kimi API
const API_URL = 'https://api.moonshot.cn/v1/chat/completions';
const API_KEY = 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m';
const MODEL = 'moonshot-v1-32k';
// Ollama
// const API_URL = 'http://192.168.0.106:11434/api/chat';
// const API_KEY = ''; // API Key
// const MODEL = 'deepseek-r1:32b';
//
const SYSTEM_PROMPT = [
@ -451,7 +451,8 @@ export default {
timeout: 60000 // 60
});
let rawResponse = data?.choices?.[0]?.message?.content ?? '无法解析模型输出';
// Kimi API (OpenAI ) Ollama
let rawResponse = data?.choices?.[0]?.message?.content ?? data?.message?.content ?? '无法解析模型输出';
//
rawResponse = rawResponse

View File

@ -709,14 +709,14 @@ export default {
},
/** AI分析报告内容 */
async generateAIAnalysis(reportContent, reportTitle, reportType) {
// Ollama
const API_URL = 'http://192.168.0.106:11434/api/chat';
const API_KEY = ''; // API Key
const MODEL = 'deepseek-r1:32b';
// Kimi API
// const API_URL = 'https://api.moonshot.cn/v1/chat/completions';
// const API_KEY = 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m';
// const MODEL = 'moonshot-v1-32k';
// Kimi API
const API_URL = 'https://api.moonshot.cn/v1/chat/completions';
const API_KEY = 'sk-U9fdriPxwBcrpWW0Ite3N0eVtX7VxnqqqYUIBAdWd1hgEA9m';
const MODEL = 'moonshot-v1-32k';
// Ollama
// const API_URL = 'http://192.168.0.106:11434/api/chat';
// const API_KEY = ''; // API Key
// const MODEL = 'deepseek-r1:32b';
//
const SYSTEM_PROMPT = [
@ -752,7 +752,10 @@ export default {
timeout: 60000 // 60
});
let rawResponse = data?.choices?.[0]?.message?.content ?? '';
console.log('AI响应数据:', data);
// Kimi API (OpenAI ) Ollama
let rawResponse = data?.choices?.[0]?.message?.content ?? data?.message?.content ?? '';
//
rawResponse = rawResponse

View File

@ -68,7 +68,7 @@
* 作用显示所有开放的心理测试题学员可以选择进行测试
*/
import { listScale } from "@/api/psychology/scale"
import { startAssessment, pausedAssessmentList, resumeAssessment } from "@/api/psychology/assessment"
import { startAssessment, pausedAssessmentList, resumeAssessment, resetAssessment } from "@/api/psychology/assessment"
import { Message } from 'element-ui'
export default {
@ -304,17 +304,36 @@ export default {
}
this.loading = true
const { delAssessment } = require("@/api/psychology/assessment")
delAssessment(pausedRecord.assessmentId)
.then(() => {
//
// 使 resetAssessment API
const resetData = {
scaleId: pausedRecord.scaleId || test.scaleId,
targetUserId: pausedRecord.userId,
assesseeName: pausedRecord.assesseeName,
assesseeGender: pausedRecord.assesseeGender || '0',
assesseeAge: pausedRecord.assesseeAge || 0,
assesseePhone: pausedRecord.assesseePhone,
anonymous: false
}
resetAssessment(resetData)
.then(response => {
if (response.code === 200) {
//
this.loadPausedList()
this.createAssessment(test)
const assessmentId = response.data
this.$router.push({
path: '/psychology/assessment/taking',
query: { assessmentId: assessmentId }
})
} else {
Message.error(response.msg || "重置测评失败")
}
this.loading = false
})
.catch(error => {
console.error("删除暂停记录失败:", error)
console.error("重置测评失败:", error)
this.loading = false
Message.error("删除旧记录失败,请稍后重试")
Message.error("重置测评失败,请稍后重试")
})
},