From 2e7104c0c69c573d96dbec92698d5be587a1fb51 Mon Sep 17 00:00:00 2001 From: xiao12feng8 <120912171+xiao12feng8@users.noreply.github.com> Date: Sat, 22 Nov 2025 21:26:49 +0800 Subject: [PATCH] =?UTF-8?q?=E9=97=AE=E5=8D=B7=E5=92=8C=E8=AD=A6=E5=91=8Abu?= =?UTF-8?q?g=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../psychology/PsyAssessmentController.java | 29 +- .../PsyAssessmentReportController.java | 61 ++-- .../PsyQuestionnaireAnswerController.java | 115 +++++-- .../PsyQuestionnaireItemController.java | 11 + .../domain/psychology/PsyAssessment.java | 13 + .../psychology/PsyAssessmentReport.java | 13 + .../system/domain/vo/AssessmentStartVO.java | 13 + .../psychology/PsyAssessmentServiceImpl.java | 33 ++ .../PsyQuestionnaireAnswerServiceImpl.java | 220 ++++++++++--- .../PsyQuestionnaireItemServiceImpl.java | 108 ++++++- .../psychology/PsyWarningServiceImpl.java | 169 ++++++++++ .../IPsyQuestionnaireItemService.java | 8 + .../system/psychology/PsyAssessmentMapper.xml | 6 +- .../system/psychology/PsyWarningMapper.xml | 7 +- .../psychology/PsyWarningRuleMapper.xml | 16 +- xinli-ui/src/api/psychology/assessment.js | 15 +- .../src/api/psychology/questionnaireAnswer.js | 23 +- .../src/api/psychology/questionnaireItem.js | 8 + xinli-ui/src/layout/components/AppMain.vue | 8 + xinli-ui/src/views/index.vue | 4 +- .../src/views/psychology/assessment/index.vue | 69 ++++- .../src/views/psychology/assessment/start.vue | 64 +++- .../views/psychology/assessment/taking.vue | 47 ++- .../views/psychology/questionnaire/index.vue | 24 +- .../views/psychology/questionnaire/item.vue | 73 +++-- .../views/psychology/questionnaire/start.vue | 18 +- .../views/psychology/questionnaire/taking.vue | 50 ++- .../src/views/psychology/report/detail.vue | 8 + .../src/views/psychology/report/index.vue | 292 +++++++++++++++++- .../src/views/psychology/scale/factor.vue | 44 ++- xinli-ui/src/views/psychology/scale/item.vue | 42 ++- .../src/views/psychology/warning/index.vue | 128 ++++++-- .../src/views/psychology/warning/rule.vue | 241 ++++++++++++--- .../src/views/system/menu/menuCleanup.vue | 8 +- 34 files changed, 1687 insertions(+), 301 deletions(-) diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java index 9d60a32b..17d426b0 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java @@ -168,18 +168,23 @@ public class PsyAssessmentController extends BaseController public AjaxResult start(@Validated @RequestBody AssessmentStartVO startVO) { try { - Long userId = null; - String username = null; + Long currentUserId = null; + String currentUsername = null; // 尝试获取当前登录用户信息 try { - userId = SecurityUtils.getUserId(); - username = SecurityUtils.getUsername(); + currentUserId = SecurityUtils.getUserId(); + 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; + PsyAssessment assessment = new PsyAssessment(); assessment.setScaleId(startVO.getScaleId()); assessment.setAssesseeName(startVO.getAssesseeName()); @@ -191,20 +196,20 @@ public class PsyAssessmentController extends BaseController assessment.setIpAddress(IpUtils.getIpAddr()); assessment.setUserAgent(ServletUtils.getRequest().getHeader("User-Agent")); - // 设置用户ID(如果获取到了) - if (userId != null) { - assessment.setUserId(userId); + // 设置用户ID(优先使用targetUserId) + if (assessmentUserId != null) { + assessment.setUserId(assessmentUserId); } - // 设置创建者(如果获取到了) - if (username != null && !username.isEmpty()) { - assessment.setCreateBy(username); + // 设置创建者(记录是谁创建的测评) + if (currentUsername != null && !currentUsername.isEmpty()) { + assessment.setCreateBy(currentUsername); } else { assessment.setCreateBy("system"); // 默认值 } - logger.info("创建测评 - scaleId: {}, userId: {}, assesseeName: {}", - startVO.getScaleId(), userId, startVO.getAssesseeName()); + logger.info("创建测评 - scaleId: {}, targetUserId: {}, assessmentUserId: {}, currentUserId: {}, assesseeName: {}", + startVO.getScaleId(), startVO.getTargetUserId(), assessmentUserId, currentUserId, startVO.getAssesseeName()); int result = assessmentService.insertAssessment(assessment); diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentReportController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentReportController.java index ceab0b99..6ae9f612 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentReportController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentReportController.java @@ -91,32 +91,25 @@ public class PsyAssessmentReportController extends BaseController */ @PreAuthorize("@ss.hasPermi('psychology:report:list')") @GetMapping("/list") - public TableDataInfo list(PsyAssessmentReport report) + public TableDataInfo list(PsyAssessmentReport report, Long userId) { - System.out.println("开始查询报告列表"); + System.out.println("开始查询报告列表,sourceType: " + report.getSourceType() + ", userId: " + userId); // 由于需要合并两种报告,需要手动分页,所以先清理分页参数 clearPage(); - // 查询测评报告(不使用分页,获取全部数据) - List assessmentReports = reportService.selectReportList(report); - System.out.println("查询到测评报告数量: " + (assessmentReports != null ? assessmentReports.size() : 0)); - - // 查询问卷报告(不使用分页,获取全部数据) - PsyQuestionnaireReport questionnaireReport = new PsyQuestionnaireReport(); - if (report.getReportType() != null && !report.getReportType().isEmpty()) { - questionnaireReport.setReportType(report.getReportType()); - } - if (report.getIsGenerated() != null && !report.getIsGenerated().isEmpty()) { - questionnaireReport.setIsGenerated(report.getIsGenerated()); - } - List questionnaireReports = questionnaireReportMapper.selectReportList(questionnaireReport); - System.out.println("查询到问卷报告数量: " + (questionnaireReports != null ? questionnaireReports.size() : 0)); + // 获取来源类型过滤参数 + String sourceTypeFilter = report.getSourceType(); // 合并报告列表(转换为统一的VO格式) List allReports = new ArrayList<>(); - // 添加测评报告 - for (PsyAssessmentReport ar : assessmentReports) { + // 如果未指定sourceType或指定为"assessment",查询测评报告 + if (sourceTypeFilter == null || sourceTypeFilter.isEmpty() || "assessment".equals(sourceTypeFilter)) { + List assessmentReports = reportService.selectReportList(report); + System.out.println("查询到测评报告数量: " + (assessmentReports != null ? assessmentReports.size() : 0)); + + // 添加测评报告 + for (PsyAssessmentReport ar : assessmentReports) { ReportVO vo = new ReportVO(); vo.setReportId(ar.getReportId()); vo.setSourceType("assessment"); @@ -133,17 +126,34 @@ public class PsyAssessmentReportController extends BaseController PsyAssessment assessment = assessmentService.selectAssessmentById(ar.getAssessmentId()); if (assessment != null) { vo.setUserId(assessment.getUserId()); + // 如果指定了userId过滤,跳过不匹配的记录 + if (userId != null && !userId.equals(assessment.getUserId())) { + continue; + } // 获取用户档案信息编号 com.ddnai.system.domain.psychology.PsyUserProfile profile = profileService.selectProfileByUserId(assessment.getUserId()); if (profile != null) { vo.setInfoNumber(profile.getInfoNumber()); } } - allReports.add(vo); + allReports.add(vo); + } } - // 添加问卷报告 - for (PsyQuestionnaireReport qr : questionnaireReports) { + // 如果未指定sourceType或指定为"questionnaire",查询问卷报告 + if (sourceTypeFilter == null || sourceTypeFilter.isEmpty() || "questionnaire".equals(sourceTypeFilter)) { + PsyQuestionnaireReport questionnaireReport = new PsyQuestionnaireReport(); + if (report.getReportType() != null && !report.getReportType().isEmpty()) { + questionnaireReport.setReportType(report.getReportType()); + } + if (report.getIsGenerated() != null && !report.getIsGenerated().isEmpty()) { + questionnaireReport.setIsGenerated(report.getIsGenerated()); + } + List questionnaireReports = questionnaireReportMapper.selectReportList(questionnaireReport); + System.out.println("查询到问卷报告数量: " + (questionnaireReports != null ? questionnaireReports.size() : 0)); + + // 添加问卷报告 + for (PsyQuestionnaireReport qr : questionnaireReports) { ReportVO vo = new ReportVO(); vo.setReportId(qr.getReportId()); vo.setSourceType("questionnaire"); @@ -160,14 +170,19 @@ public class PsyAssessmentReportController extends BaseController com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer answer = questionnaireAnswerService.selectAnswerById(qr.getAnswerId()); if (answer != null) { vo.setUserId(answer.getUserId()); + // 如果指定了userId过滤,跳过不匹配的记录 + if (userId != null && !userId.equals(answer.getUserId())) { + continue; + } // 获取用户档案信息编号 com.ddnai.system.domain.psychology.PsyUserProfile profile = profileService.selectProfileByUserId(answer.getUserId()); if (profile != null) { vo.setInfoNumber(profile.getInfoNumber()); } } - allReports.add(vo); - System.out.println("添加问卷报告: reportId=" + qr.getReportId() + ", answerId=" + qr.getAnswerId() + ", title=" + qr.getReportTitle()); + allReports.add(vo); + System.out.println("添加问卷报告: reportId=" + qr.getReportId() + ", answerId=" + qr.getAnswerId() + ", title=" + qr.getReportTitle()); + } } System.out.println("合并后总报告数: " + allReports.size()); diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireAnswerController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireAnswerController.java index 887a2c62..47c4a18b 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireAnswerController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireAnswerController.java @@ -1,5 +1,6 @@ package com.ddnai.web.controller.psychology; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -80,6 +81,7 @@ public class PsyQuestionnaireAnswerController extends BaseController /** * 开始问卷答题 + * 支持重复答题:每次都创建新的答题记录 */ @PostMapping("/start") public AjaxResult start(@RequestBody Map params) @@ -90,6 +92,13 @@ public class PsyQuestionnaireAnswerController extends BaseController // 获取被测试用户ID:如果前端传递了userId(管理员代测),则使用传递的userId;否则使用当前登录用户ID Long userId = params.get("userId") != null ? Long.valueOf(params.get("userId").toString()) : SecurityUtils.getUserId(); + System.out.println("========================================"); + System.out.println("📝 开始问卷答题"); + System.out.println("questionnaireId: " + questionnaireId + ", userId: " + userId); + System.out.println("允许重复答题,创建新的答题记录"); + System.out.println("========================================"); + + // 每次都创建新的答题记录,支持重复答题 PsyQuestionnaireAnswer answer = new PsyQuestionnaireAnswer(); answer.setQuestionnaireId(questionnaireId); answer.setUserId(userId); // 使用被测试用户ID @@ -102,8 +111,10 @@ public class PsyQuestionnaireAnswerController extends BaseController if (result > 0) { + System.out.println("✅ 创建答题记录成功,answerId: " + answer.getAnswerId()); return success(answer.getAnswerId()); } + System.err.println("❌ 创建答题记录失败"); return error("开始答题失败"); } @@ -166,7 +177,10 @@ public class PsyQuestionnaireAnswerController extends BaseController { try { - System.out.println("开始提交问卷,answerId: " + answerId + ", 用户: " + SecurityUtils.getUsername()); + System.out.println("========================================"); + System.out.println("🔧 [修复版本 2025-11-22] 开始提交问卷"); + System.out.println("answerId: " + answerId + ", 用户: " + SecurityUtils.getUsername()); + System.out.println("========================================"); PsyQuestionnaireAnswer answer = answerService.selectAnswerById(answerId); if (answer == null) @@ -241,8 +255,35 @@ public class PsyQuestionnaireAnswerController extends BaseController } } - // 按总分降序排序,总分相同按提交时间升序 - filteredList.sort((a, b) -> { + // 按用户分组,每个用户只保留最高分的记录 + Map userBestScores = new HashMap<>(); + for (PsyQuestionnaireAnswer answer : filteredList) { + Long userId = answer.getUserId(); + if (userId == null) continue; + + PsyQuestionnaireAnswer existing = userBestScores.get(userId); + if (existing == null) { + userBestScores.put(userId, answer); + } else { + // 比较分数,保留更高的 + BigDecimal existingScore = existing.getTotalScore() != null ? existing.getTotalScore() : BigDecimal.ZERO; + BigDecimal currentScore = answer.getTotalScore() != null ? answer.getTotalScore() : BigDecimal.ZERO; + + if (currentScore.compareTo(existingScore) > 0) { + userBestScores.put(userId, answer); + } else if (currentScore.compareTo(existingScore) == 0) { + // 分数相同,保留提交时间更早的 + if (answer.getSubmitTime() != null && existing.getSubmitTime() != null + && answer.getSubmitTime().before(existing.getSubmitTime())) { + userBestScores.put(userId, answer); + } + } + } + } + + // 转换为列表并按总分降序排序 + List uniqueList = new ArrayList<>(userBestScores.values()); + uniqueList.sort((a, b) -> { if (a.getTotalScore() == null && b.getTotalScore() == null) return 0; if (a.getTotalScore() == null) return 1; if (b.getTotalScore() == null) return -1; @@ -254,31 +295,17 @@ public class PsyQuestionnaireAnswerController extends BaseController } return 0; }); + + // 设置排名 + int rank = 1; + for (PsyQuestionnaireAnswer answer : uniqueList) { + answer.setRank(rank++); + } // 补充未填写的答题人姓名(默认使用系统用户昵称/账号) - enrichRespondentNames(filteredList); + enrichRespondentNames(uniqueList); - return success(filteredList); - } - - /** - * 手动生成问卷报告(用于测试和修复) - */ - @PostMapping("/generateReport/{answerId}") - public AjaxResult generateReport(@PathVariable Long answerId) - { - try - { - // 通过反射调用私有方法,或者将方法改为public - // 这里我们直接调用service的公共方法 - // 由于generateQuestionnaireReport是private,我们需要创建一个公共方法 - answerService.generateReport(answerId); - return success("报告生成成功"); - } - catch (Exception e) - { - return error("报告生成失败:" + e.getMessage()); - } + return success(uniqueList); } /** @@ -392,5 +419,43 @@ public class PsyQuestionnaireAnswerController extends BaseController answer.setRespondentName(cachedName); } } + + /** + * 手动触发报告生成(用于补救) + */ + @PostMapping("/generateReport/{answerId}") + public AjaxResult manualGenerateReport(@PathVariable Long answerId) + { + try + { + System.out.println("========================================"); + System.out.println("🔧 手动触发报告生成"); + System.out.println("answerId: " + answerId); + System.out.println("========================================"); + + PsyQuestionnaireAnswer answer = answerService.selectAnswerById(answerId); + if (answer == null) + { + return error("答题记录不存在"); + } + + if (!"1".equals(answer.getStatus())) + { + return error("问卷未提交,无法生成报告"); + } + + // 调用报告生成服务 + answerService.generateReport(answerId); + + System.out.println("✅ 手动报告生成完成"); + return success("报告生成成功"); + } + catch (Exception e) + { + System.err.println("❌ 手动报告生成失败: " + e.getMessage()); + e.printStackTrace(); + return error("报告生成失败:" + e.getMessage()); + } + } } diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireItemController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireItemController.java index 1958e681..e9574a97 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireItemController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyQuestionnaireItemController.java @@ -84,5 +84,16 @@ public class PsyQuestionnaireItemController extends BaseController { return toAjax(itemService.deleteItemByIds(itemIds)); } + + /** + * 更新问卷总分(根据题目分数自动计算) + */ + @PreAuthorize("@ss.hasPermi('psychology:questionnaire:edit')") + @Log(title = "更新问卷总分", businessType = BusinessType.UPDATE) + @PutMapping("/updateTotalScore/{questionnaireId}") + public AjaxResult updateTotalScore(@PathVariable Long questionnaireId) + { + return toAjax(itemService.updateQuestionnaireTotalScore(questionnaireId)); + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessment.java b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessment.java index e4fcd267..0b7db055 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessment.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessment.java @@ -79,6 +79,9 @@ public class PsyAssessment extends BaseEntity /** 用户代理 */ private String userAgent; + /** 是否有报告(关联查询字段,不存储在表中) */ + private Boolean hasReport; + public Long getAssessmentId() { return assessmentId; @@ -279,6 +282,16 @@ public class PsyAssessment extends BaseEntity this.userAgent = userAgent; } + public Boolean getHasReport() + { + return hasReport; + } + + public void setHasReport(Boolean hasReport) + { + this.hasReport = hasReport; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessmentReport.java b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessmentReport.java index 48f1cb1e..f0fda280 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessmentReport.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyAssessmentReport.java @@ -48,6 +48,9 @@ public class PsyAssessmentReport extends BaseEntity @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private java.util.Date generateTime; + /** 来源类型(用于查询过滤,不存储到数据库) */ + private String sourceType; + public Long getReportId() { return reportId; @@ -148,6 +151,16 @@ public class PsyAssessmentReport extends BaseEntity this.generateTime = generateTime; } + public String getSourceType() + { + return sourceType; + } + + public void setSourceType(String sourceType) + { + this.sourceType = sourceType; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/domain/vo/AssessmentStartVO.java b/ry-xinli-system/src/main/java/com/ddnai/system/domain/vo/AssessmentStartVO.java index 7cd2e0d7..80023489 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/domain/vo/AssessmentStartVO.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/domain/vo/AssessmentStartVO.java @@ -28,6 +28,9 @@ public class AssessmentStartVO /** 是否匿名测评 */ private Boolean anonymous; + /** 目标用户ID(管理员代替用户测评时使用) */ + private Long targetUserId; + public Long getScaleId() { return scaleId; @@ -87,5 +90,15 @@ public class AssessmentStartVO { this.anonymous = anonymous; } + + public Long getTargetUserId() + { + return targetUserId; + } + + public void setTargetUserId(Long targetUserId) + { + this.targetUserId = targetUserId; + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyAssessmentServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyAssessmentServiceImpl.java index e9730a57..64dede31 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyAssessmentServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyAssessmentServiceImpl.java @@ -49,6 +49,18 @@ public class PsyAssessmentServiceImpl implements IPsyAssessmentService @Autowired private IPsyUserProfileService userProfileService; + @Autowired + private com.ddnai.system.mapper.psychology.PsyWarningMapper warningMapper; + + @Autowired + private com.ddnai.system.mapper.psychology.PsyFactorScoreMapper factorScoreMapper; + + @Autowired + private com.ddnai.system.mapper.psychology.PsyAssessmentAnswerMapper answerMapper; + + @Autowired + private com.ddnai.system.mapper.psychology.PsyAssessmentReportMapper reportMapper; + @Override public PsyAssessment selectAssessmentById(Long assessmentId) { @@ -88,6 +100,27 @@ public class PsyAssessmentServiceImpl implements IPsyAssessmentService @Override public int deleteAssessmentByIds(Long[] assessmentIds) { + // 级联删除相关数据 + for (Long assessmentId : assessmentIds) + { + // 1. 删除预警记录 + warningMapper.deleteWarningByAssessmentId(assessmentId); + + // 2. 删除因子得分 + factorScoreMapper.deleteFactorScoreByAssessmentId(assessmentId); + + // 3. 删除答案记录 + answerMapper.deleteAnswerByAssessmentId(assessmentId); + + // 4. 删除报告(如果存在) + PsyAssessmentReport report = reportMapper.selectReportByAssessmentId(assessmentId); + if (report != null) + { + reportMapper.deleteReportById(report.getReportId()); + } + } + + // 5. 最后删除测评记录 return assessmentMapper.deleteAssessmentByIds(assessmentIds); } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireAnswerServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireAnswerServiceImpl.java index 9ec5dfee..aa6f552e 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireAnswerServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireAnswerServiceImpl.java @@ -24,7 +24,9 @@ import com.ddnai.common.utils.DateUtils; import com.ddnai.system.domain.psychology.PsyQuestionnaire; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.math.RoundingMode; @@ -220,35 +222,22 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe int result = answerMapper.updateAnswer(answer); - // 异步更新排名(避免阻塞提交流程) - final Long questionnaireIdForRank = answer.getQuestionnaireId(); - CompletableFuture.runAsync(() -> { + // 自动生成报告(和量表一样的简洁方式) + if (result > 0) { try { - // 延迟50ms确保事务提交完成 - Thread.sleep(50); - updateRank(questionnaireIdForRank); - System.out.println("异步排名更新完成,questionnaireId: " + questionnaireIdForRank); + System.out.println("========================================"); + System.out.println("📊 自动生成问卷报告"); + System.out.println("answerId: " + answerId); + System.out.println("========================================"); + + generateQuestionnaireReport(answerId); + + System.out.println("✅ 报告生成成功"); } catch (Exception e) { - System.err.println("异步更新排名失败,questionnaireId: " + questionnaireIdForRank); + // 报告生成失败,但不影响问卷提交 + System.err.println("⚠️ 报告生成失败: " + e.getMessage()); e.printStackTrace(); } - }); - - // 异步生成问卷报告(避免阻塞提交流程) - if (result > 0) { - // 使用异步任务生成报告,不阻塞当前事务 - CompletableFuture.runAsync(() -> { - try { - // 延迟100ms确保事务提交完成 - Thread.sleep(100); - generateQuestionnaireReport(answerId); - System.out.println("异步问卷报告生成完成,answerId: " + answerId); - } catch (Exception e) { - System.err.println("异步生成问卷报告失败,answerId: " + answerId); - System.err.println("错误信息: " + e.getMessage()); - e.printStackTrace(); - } - }); } return result; @@ -269,14 +258,20 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe private void generateQuestionnaireReport(Long answerId) { try { - System.out.println("开始生成问卷报告,answerId: " + answerId); + System.out.println("\n"); + System.out.println("████████████████████████████████████████"); + System.out.println("🔧 [修复版本 2025-11-22] 开始生成问卷报告"); + System.out.println("answerId: " + answerId); + System.out.println("时间: " + new java.util.Date()); + System.out.println("████████████████████████████████████████"); // 获取答题记录 PsyQuestionnaireAnswer answer = answerMapper.selectAnswerById(answerId); if (answer == null) { - System.err.println("答题记录不存在,answerId: " + answerId); + System.err.println("!!! 错误:答题记录不存在,answerId: " + answerId); return; } + System.out.println("✓ 获取答题记录成功,questionnaireId: " + answer.getQuestionnaireId()); // 获取问卷信息 PsyQuestionnaire questionnaire = questionnaireService.selectQuestionnaireById(answer.getQuestionnaireId()); @@ -457,16 +452,26 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe report.setCreateBy(SecurityUtils.getUsername()); report.setCreateTime(DateUtils.getNowDate()); int insertResult = reportMapper.insertReport(report); - System.out.println("创建新报告结果: " + insertResult + ", reportId: " + report.getReportId() + ", 报告状态: " + isGenerated); + System.out.println("✓ 创建新报告结果: " + insertResult + ", reportId: " + report.getReportId() + ", 报告状态: " + isGenerated); if (insertResult <= 0) { - System.err.println("警告:报告插入失败,insertResult: " + insertResult); + System.err.println("!!! 警告:报告插入失败,insertResult: " + insertResult); + } else { + System.out.println("✓✓✓ 报告已成功插入数据库 ✓✓✓"); } } System.out.println("报告内容长度: " + reportContent.length()); System.out.println("报告摘要: " + summary); - System.out.println("问卷报告生成成功,answerId: " + answerId + ", reportId: " + report.getReportId()); + System.out.println("\n"); + System.out.println("████████████████████████████████████████"); + System.out.println("✅✅✅ 问卷报告生成成功!✅✅✅"); + System.out.println("🔧 [修复版本 2025-11-22]"); + System.out.println("answerId: " + answerId); + System.out.println("reportId: " + report.getReportId()); + System.out.println("时间: " + new java.util.Date()); + System.out.println("████████████████████████████████████████"); + System.out.println("\n"); } catch (Exception e) { System.err.println("生成问卷报告时发生异常,answerId: " + answerId); e.printStackTrace(); @@ -541,7 +546,7 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe return calculateInputScore(detail, correctOptions, itemScore); case "sort": // 排序 - return calculateSortScore(detail, correctOptions, itemScore); + return calculateSortScore(item, detail, allOptions, itemScore); case "calculate": // 计算 return calculateCalculateScore(detail, correctOptions, itemScore); @@ -729,15 +734,21 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe /** * 计算排序题得分 + * 使用题目的remark字段作为正确答案 */ - private BigDecimal calculateSortScore(PsyQuestionnaireAnswerDetail detail, List correctOptions, - BigDecimal itemScore) + private BigDecimal calculateSortScore(PsyQuestionnaireItem item, PsyQuestionnaireAnswerDetail detail, + List allOptions, BigDecimal itemScore) { + System.out.println("🔧 [排序题评分] itemId: " + item.getItemId() + ", 题目: " + item.getItemContent()); + if (detail.getOptionIds() == null || detail.getOptionIds().trim().isEmpty()) { + System.out.println("⚠️ 用户未作答排序题"); return BigDecimal.ZERO; } + System.out.println("📝 用户答案: " + detail.getOptionIds()); + // 解析用户排序的选项ID列表 List userOrder = Arrays.stream(detail.getOptionIds().split(",")) .map(String::trim) @@ -745,40 +756,82 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe .map(Long::valueOf) .collect(Collectors.toList()); - // 获取正确答案的排序(按sort_order排序) - List correctOrder = correctOptions.stream() - .sorted((a, b) -> Integer.compare( - a.getSortOrder() != null ? a.getSortOrder() : 0, - b.getSortOrder() != null ? b.getSortOrder() : 0)) - .map(PsyQuestionnaireOption::getOptionId) - .collect(Collectors.toList()); + // 获取正确答案 + List correctOrder = new ArrayList<>(); + if (item.getRemark() != null && !item.getRemark().trim().isEmpty()) + { + // 使用题目的remark字段存储正确答案(格式:A,B,C,D 或 1,2,3,4) + correctOrder = Arrays.stream(item.getRemark().split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); + } + else + { + // 兼容旧数据:如果没有remark,使用选项的sortOrder + correctOrder = allOptions.stream() + .sorted((a, b) -> Integer.compare( + a.getSortOrder() != null ? a.getSortOrder() : 0, + b.getSortOrder() != null ? b.getSortOrder() : 0)) + .map(opt -> opt.getOptionCode() != null ? opt.getOptionCode() : String.valueOf(opt.getOptionId())) + .collect(Collectors.toList()); + } - if (userOrder.size() != correctOrder.size()) + // 建立选项编码到ID的映射 + Map codeToIdMap = new HashMap<>(); + for (PsyQuestionnaireOption option : allOptions) + { + String code = option.getOptionCode() != null ? option.getOptionCode() : String.valueOf(option.getOptionId()); + codeToIdMap.put(code.toUpperCase(), option.getOptionId()); + codeToIdMap.put(String.valueOf(option.getOptionId()), option.getOptionId()); + } + + // 将正确答案的编码转换为ID列表 + List correctOrderIds = new ArrayList<>(); + for (String code : correctOrder) + { + Long optionId = codeToIdMap.get(code.toUpperCase()); + if (optionId != null) + { + correctOrderIds.add(optionId); + } + } + + if (correctOrderIds.isEmpty() || userOrder.size() != correctOrderIds.size()) { return BigDecimal.ZERO; } // 检查顺序是否完全正确 + System.out.println("✓ 正确答案ID: " + correctOrderIds); + System.out.println("✓ 用户答案ID: " + userOrder); + boolean isCorrect = true; for (int i = 0; i < userOrder.size(); i++) { - if (!userOrder.get(i).equals(correctOrder.get(i))) + if (!userOrder.get(i).equals(correctOrderIds.get(i))) { isCorrect = false; + System.out.println("❌ 位置" + i + "不匹配: 用户=" + userOrder.get(i) + ", 正确=" + correctOrderIds.get(i)); break; } } if (isCorrect) { + System.out.println("✅ 排序完全正确!得分: " + itemScore); return itemScore; } + else + { + System.out.println("❌ 排序错误,得分: 0"); + } // 部分正确:计算正确位置的数量 int correctCount = 0; for (int i = 0; i < userOrder.size(); i++) { - if (userOrder.get(i).equals(correctOrder.get(i))) + if (userOrder.get(i).equals(correctOrderIds.get(i))) { correctCount++; } @@ -787,7 +840,7 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe // 按比例得分 if (correctCount > 0) { - BigDecimal ratio = new BigDecimal(correctCount).divide(new BigDecimal(correctOrder.size()), 4, RoundingMode.HALF_UP); + BigDecimal ratio = new BigDecimal(correctCount).divide(new BigDecimal(correctOrderIds.size()), 4, RoundingMode.HALF_UP); return itemScore.multiply(ratio); } @@ -1095,5 +1148,84 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe return result; } + + /** + * 强制生成简化报告 - 备用方案 + * 当正常报告生成失败时使用此方法 + */ + @Transactional + public void forceGenerateSimpleReport(Long answerId) { + try { + System.out.println("========================================"); + System.out.println("🚨 使用强制简化报告生成"); + System.out.println("answerId: " + answerId); + System.out.println("========================================"); + + // 获取答题记录 + PsyQuestionnaireAnswer answer = answerMapper.selectAnswerById(answerId); + if (answer == null) { + System.err.println("❌ 答题记录不存在"); + return; + } + + // 获取问卷信息 + PsyQuestionnaire questionnaire = questionnaireService.selectQuestionnaireById(answer.getQuestionnaireId()); + if (questionnaire == null) { + System.err.println("❌ 问卷不存在"); + return; + } + + // 检查是否已有报告 + PsyQuestionnaireReport existingReport = reportMapper.selectReportByAnswerId(answerId); + + // 生成简化的报告内容 + StringBuilder content = new StringBuilder(); + content.append("
"); + content.append("

").append(questionnaire.getQuestionnaireName()).append(" - 答题报告

"); + content.append("

答题时间:").append(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, answer.getStartTime())).append("

"); + content.append("

总得分:").append(answer.getTotalScore() != null ? answer.getTotalScore() : "0").append("

"); + content.append("

状态:已完成

"); + content.append("
"); + + String summary = "总分:" + (answer.getTotalScore() != null ? answer.getTotalScore() : "0"); + + if (existingReport != null) { + // 更新现有报告 + System.out.println("✓ 更新现有报告,reportId: " + existingReport.getReportId()); + existingReport.setReportContent(content.toString()); + existingReport.setSummary(summary); + existingReport.setIsGenerated("1"); + existingReport.setGenerateTime(DateUtils.getNowDate()); + existingReport.setUpdateBy(SecurityUtils.getUsername()); + existingReport.setUpdateTime(DateUtils.getNowDate()); + reportMapper.updateReport(existingReport); + } else { + // 创建新报告 + System.out.println("✓ 创建新报告"); + PsyQuestionnaireReport report = new PsyQuestionnaireReport(); + report.setAnswerId(answerId); + report.setReportContent(content.toString()); + report.setSummary(summary); + report.setIsGenerated("1"); + report.setGenerateTime(DateUtils.getNowDate()); + report.setCreateBy(SecurityUtils.getUsername()); + report.setCreateTime(DateUtils.getNowDate()); + reportMapper.insertReport(report); + } + + System.out.println("========================================"); + System.out.println("✅ 强制简化报告生成成功!"); + System.out.println("answerId: " + answerId); + System.out.println("========================================"); + + } catch (Exception e) { + System.err.println("========================================"); + System.err.println("❌ 强制简化报告生成也失败了!"); + System.err.println("answerId: " + answerId); + System.err.println("错误: " + e.getMessage()); + System.err.println("========================================"); + e.printStackTrace(); + } + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireItemServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireItemServiceImpl.java index c52c16eb..1547f55a 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireItemServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyQuestionnaireItemServiceImpl.java @@ -1,10 +1,14 @@ package com.ddnai.system.service.impl.psychology; +import java.math.BigDecimal; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.ddnai.system.domain.psychology.PsyQuestionnaireItem; +import com.ddnai.system.domain.psychology.PsyQuestionnaire; import com.ddnai.system.mapper.psychology.PsyQuestionnaireItemMapper; +import com.ddnai.system.mapper.psychology.PsyQuestionnaireMapper; import com.ddnai.system.service.psychology.IPsyQuestionnaireItemService; /** @@ -17,6 +21,9 @@ public class PsyQuestionnaireItemServiceImpl implements IPsyQuestionnaireItemSer { @Autowired private PsyQuestionnaireItemMapper itemMapper; + + @Autowired + private PsyQuestionnaireMapper questionnaireMapper; /** * 查询题目信息 @@ -61,9 +68,16 @@ public class PsyQuestionnaireItemServiceImpl implements IPsyQuestionnaireItemSer * @return 结果 */ @Override + @Transactional public int insertItem(PsyQuestionnaireItem item) { - return itemMapper.insertItem(item); + int result = itemMapper.insertItem(item); + if (result > 0 && item.getQuestionnaireId() != null) + { + // 自动更新问卷总分 + updateQuestionnaireTotalScore(item.getQuestionnaireId()); + } + return result; } /** @@ -73,9 +87,16 @@ public class PsyQuestionnaireItemServiceImpl implements IPsyQuestionnaireItemSer * @return 结果 */ @Override + @Transactional public int updateItem(PsyQuestionnaireItem item) { - return itemMapper.updateItem(item); + int result = itemMapper.updateItem(item); + if (result > 0 && item.getQuestionnaireId() != null) + { + // 自动更新问卷总分 + updateQuestionnaireTotalScore(item.getQuestionnaireId()); + } + return result; } /** @@ -85,9 +106,25 @@ public class PsyQuestionnaireItemServiceImpl implements IPsyQuestionnaireItemSer * @return 结果 */ @Override + @Transactional public int deleteItemByIds(Long[] itemIds) { - return itemMapper.deleteItemByIds(itemIds); + if (itemIds == null || itemIds.length == 0) + { + return 0; + } + + // 获取第一个题目的问卷ID(假设批量删除的题目属于同一个问卷) + PsyQuestionnaireItem firstItem = itemMapper.selectItemById(itemIds[0]); + Long questionnaireId = firstItem != null ? firstItem.getQuestionnaireId() : null; + + int result = itemMapper.deleteItemByIds(itemIds); + if (result > 0 && questionnaireId != null) + { + // 自动更新问卷总分 + updateQuestionnaireTotalScore(questionnaireId); + } + return result; } /** @@ -97,9 +134,72 @@ public class PsyQuestionnaireItemServiceImpl implements IPsyQuestionnaireItemSer * @return 结果 */ @Override + @Transactional public int deleteItemById(Long itemId) { - return itemMapper.deleteItemById(itemId); + // 先获取题目信息,以便获取问卷ID + PsyQuestionnaireItem item = itemMapper.selectItemById(itemId); + Long questionnaireId = item != null ? item.getQuestionnaireId() : null; + + int result = itemMapper.deleteItemById(itemId); + if (result > 0 && questionnaireId != null) + { + // 自动更新问卷总分 + updateQuestionnaireTotalScore(questionnaireId); + } + return result; + } + + /** + * 更新问卷总分(根据题目分数自动计算) + * + * @param questionnaireId 问卷ID + * @return 结果 + */ + @Override + public int updateQuestionnaireTotalScore(Long questionnaireId) + { + try + { + // 查询该问卷的所有题目 + List items = itemMapper.selectItemListByQuestionnaireId(questionnaireId); + + // 计算总分 + BigDecimal totalScore = BigDecimal.ZERO; + int itemCount = 0; + + if (items != null && !items.isEmpty()) + { + itemCount = items.size(); + for (PsyQuestionnaireItem item : items) + { + if (item.getScore() != null) + { + totalScore = totalScore.add(item.getScore()); + } + } + } + + // 更新问卷的总分和题目数量 + PsyQuestionnaire questionnaire = questionnaireMapper.selectQuestionnaireById(questionnaireId); + if (questionnaire != null) + { + questionnaire.setTotalScore(totalScore); + questionnaire.setItemCount(itemCount); + questionnaireMapper.updateQuestionnaire(questionnaire); + + System.out.println("自动更新问卷总分成功 - questionnaireId: " + questionnaireId + + ", 题目数量: " + itemCount + ", 总分: " + totalScore); + return 1; + } + return 0; + } + catch (Exception e) + { + System.err.println("自动更新问卷总分失败 - questionnaireId: " + questionnaireId); + e.printStackTrace(); + return 0; + } } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyWarningServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyWarningServiceImpl.java index c7162785..74755b7f 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyWarningServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyWarningServiceImpl.java @@ -17,6 +17,8 @@ import com.ddnai.system.service.psychology.IPsyAssessmentService; import com.ddnai.system.service.psychology.IPsyFactorScoreService; import com.ddnai.system.service.psychology.IPsyWarningRuleService; import com.ddnai.system.service.psychology.IPsyWarningService; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; /** * 危机预警 服务层实现 @@ -100,6 +102,7 @@ public class PsyWarningServiceImpl implements IPsyWarningService /** * 检查并创建预警(在报告生成后调用) * 根据预警规则匹配因子得分或总分,创建预警记录 + * 同时检查该用户是否有符合自动解除条件的预警 */ @Override @Transactional(rollbackFor = Exception.class) @@ -122,6 +125,9 @@ public class PsyWarningServiceImpl implements IPsyWarningService return 0; // 没有预警规则,不创建预警 } + // 4. 先检查并自动解除该用户的旧预警(基于新的测评分数) + checkAndAutoRelieveWarnings(assessment, factorScores, rules); + int warningCount = 0; // 4. 检查因子得分预警 @@ -257,4 +263,167 @@ public class PsyWarningServiceImpl implements IPsyWarningService return warning; } + + /** + * 检查并自动解除该用户的未处理预警 + * 当用户做新测评时,检查旧预警是否满足解除条件 + */ + private void checkAndAutoRelieveWarnings(PsyAssessment assessment, List factorScores, List rules) + { + // 1. 查询该用户在该量表下所有未处理的预警(状态为0) + PsyWarning queryWarning = new PsyWarning(); + queryWarning.setUserId(assessment.getUserId()); + queryWarning.setScaleId(assessment.getScaleId()); + queryWarning.setStatus("0"); // 只查询未处理的预警 + + List activeWarnings = warningMapper.selectWarningList(queryWarning); + if (activeWarnings == null || activeWarnings.isEmpty()) + { + return; // 没有未处理的预警,直接返回 + } + + System.out.println("检查自动解除预警:用户ID=" + assessment.getUserId() + ", 量表ID=" + assessment.getScaleId() + ", 未处理预警数=" + activeWarnings.size()); + + // 2. 遍历每个未处理的预警,检查是否满足解除条件 + for (PsyWarning warning : activeWarnings) + { + // 找到触发该预警的规则 + PsyWarningRule matchedRule = null; + for (PsyWarningRule rule : rules) + { + // 匹配因子ID(都为null或都相等) + boolean factorMatch = (warning.getFactorId() == null && rule.getFactorId() == null) || + (warning.getFactorId() != null && warning.getFactorId().equals(rule.getFactorId())); + + // 匹配预警等级 + boolean levelMatch = warning.getWarningLevel() != null && warning.getWarningLevel().equals(rule.getWarningLevel()); + + if (factorMatch && levelMatch) + { + matchedRule = rule; + break; + } + } + + if (matchedRule == null) + { + System.out.println("未找到匹配的预警规则,跳过:预警ID=" + warning.getWarningId()); + continue; + } + + // 检查规则是否启用了自动解除 + if (!"1".equals(matchedRule.getAutoRelief()) || matchedRule.getReliefCondition() == null || matchedRule.getReliefCondition().trim().isEmpty()) + { + System.out.println("规则未启用自动解除或无解除条件,跳过:规则ID=" + matchedRule.getRuleId()); + continue; + } + + // 获取当前的分数(因子分数或总分) + BigDecimal currentScore = null; + if (warning.getFactorId() != null) + { + // 因子预警,获取因子分数 + for (PsyFactorScore factorScore : factorScores) + { + if (factorScore.getFactorId().equals(warning.getFactorId())) + { + currentScore = factorScore.getFactorScore(); + break; + } + } + } + else + { + // 总分预警 + currentScore = assessment.getTotalScore(); + } + + if (currentScore == null) + { + System.out.println("无法获取当前分数,跳过:预警ID=" + warning.getWarningId()); + continue; + } + + // 检查是否满足解除条件 + if (checkReliefCondition(currentScore, matchedRule.getReliefCondition())) + { + // 满足解除条件,自动解除预警 + warning.setStatus("2"); // 已解除 + warning.setReliefTime(DateUtils.getNowDate()); + warning.setUpdateBy("system"); + warning.setUpdateTime(DateUtils.getNowDate()); + warning.setRemark("自动解除:新测评分数" + currentScore + "满足解除条件"); + + warningMapper.updateWarning(warning); + System.out.println("自动解除预警成功:预警ID=" + warning.getWarningId() + ", 当前分数=" + currentScore); + } + } + } + + /** + * 检查分数是否满足解除条件 + * 解除条件JSON格式: + * {"operator": "<", "score": 60} - 分数低于60 + * {"operator": ">", "score": 40} - 分数高于40 + * {"operator": "between", "scoreMin": 30, "scoreMax": 50} - 分数在30-50之间 + */ + private boolean checkReliefCondition(BigDecimal currentScore, String reliefConditionJson) + { + try + { + ObjectMapper mapper = new ObjectMapper(); + JsonNode condition = mapper.readTree(reliefConditionJson); + + String operator = condition.has("operator") ? condition.get("operator").asText() : null; + + if (operator == null) + { + return false; + } + + switch (operator) + { + case "<": + // 分数低于指定值 + if (condition.has("score")) + { + BigDecimal targetScore = new BigDecimal(condition.get("score").asText()); + boolean result = currentScore.compareTo(targetScore) < 0; + System.out.println("检查解除条件 (<): 当前分数=" + currentScore + ", 目标分数=" + targetScore + ", 结果=" + result); + return result; + } + break; + + case ">": + // 分数高于指定值 + if (condition.has("score")) + { + BigDecimal targetScore = new BigDecimal(condition.get("score").asText()); + boolean result = currentScore.compareTo(targetScore) > 0; + System.out.println("检查解除条件 (>): 当前分数=" + currentScore + ", 目标分数=" + targetScore + ", 结果=" + result); + return result; + } + break; + + case "between": + // 分数在指定范围内 + if (condition.has("scoreMin") && condition.has("scoreMax")) + { + BigDecimal minScore = new BigDecimal(condition.get("scoreMin").asText()); + BigDecimal maxScore = new BigDecimal(condition.get("scoreMax").asText()); + boolean result = currentScore.compareTo(minScore) >= 0 && currentScore.compareTo(maxScore) <= 0; + System.out.println("检查解除条件 (between): 当前分数=" + currentScore + ", 范围=" + minScore + "~" + maxScore + ", 结果=" + result); + return result; + } + break; + } + } + catch (Exception e) + { + System.err.println("解析解除条件失败:" + reliefConditionJson); + e.printStackTrace(); + } + + return false; + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyQuestionnaireItemService.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyQuestionnaireItemService.java index 43235c44..2f9b9232 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyQuestionnaireItemService.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyQuestionnaireItemService.java @@ -65,5 +65,13 @@ public interface IPsyQuestionnaireItemService * @return 结果 */ public int deleteItemById(Long itemId); + + /** + * 更新问卷总分(根据题目分数自动计算) + * + * @param questionnaireId 问卷ID + * @return 结果 + */ + public int updateQuestionnaireTotalScore(Long questionnaireId); } diff --git a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml index d8802182..c685a5c0 100644 --- a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml +++ b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml @@ -25,6 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -36,9 +37,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select a.assessment_id, a.scale_id, s.scale_name, a.user_id, a.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, a.create_by, a.create_time, a.update_by, a.update_time, a.remark + a.ip_address, a.user_agent, + (case when r.report_id is not null then 1 else 0 end) as has_report, + a.create_by, a.create_time, a.update_by, a.update_time, a.remark 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