Gqingci 4 giorni fa
parent
commit
2d5f0d501c

BIN
report_debug_output.docx


+ 6 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/MainBackInterview.java

@@ -1,6 +1,7 @@
 package org.dromara.main.domain;
 
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -20,10 +21,15 @@ public class MainBackInterview extends BaseEntity {
     private String intervieweeName;
     private String intervieweeRelation;
     private String intervieweeContact;
+    @TableField("qa_1")
     private String qa1;
+    @TableField("qa_2")
     private String qa2;
+    @TableField("qa_3")
     private String qa3;
+    @TableField("qa_4")
     private String qa4;
+    @TableField("qa_5")
     private String qa5;
     
     private String tenantId;

+ 3 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/MainBackRecord.java

@@ -26,6 +26,9 @@ public class MainBackRecord extends BaseEntity {
     /** 背调状态 */
     private String status;
 
+    /** 报告状态(0待填写, 1已出具) */
+    private Integer reportStatus;
+
     /** 报告地址 */
     private String reportUrl;
 

+ 7 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/mapper/MainBackInterviewMapper.java

@@ -0,0 +1,7 @@
+package org.dromara.main.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.main.domain.MainBackInterview;
+
+public interface MainBackInterviewMapper extends BaseMapperPlus<MainBackInterview, MainBackInterview> {
+}

+ 97 - 113
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/impl/MainBackOrderServiceImpl.java

@@ -25,6 +25,7 @@ import org.dromara.main.domain.MainBackRecord;
 import org.dromara.main.domain.MainOrder;
 import org.dromara.main.domain.MainPosition;
 import org.dromara.main.domain.MainPostCandidateReview;
+import org.dromara.main.domain.MainBackInterview;
 import org.dromara.main.domain.bo.MainBackOrderBo;
 import org.dromara.main.domain.bo.PortalCheckOrderCreateBo;
 import org.dromara.main.domain.MainStudent;
@@ -37,6 +38,7 @@ import org.dromara.main.domain.vo.MainBackOrderVo;
 import org.dromara.main.mapper.MainBackCandidateMapper;
 import org.dromara.main.mapper.MainBackCategoryMapper;
 import org.dromara.main.mapper.MainBackClauseMapper;
+import org.dromara.main.mapper.MainBackInterviewMapper;
 import org.dromara.main.mapper.MainBackOrderMapper;
 import org.dromara.main.mapper.MainBackRecordMapper;
 import org.dromara.main.mapper.MainOrderMapper;
@@ -94,6 +96,7 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
     private final MainStudentEducationMapper mainStudentEducationMapper;
     private final MainStudentExperienceMapper mainStudentExperienceMapper;
     private final MainPostCandidateReviewMapper mainPostCandidateReviewMapper;
+    private final MainBackInterviewMapper mainBackInterviewMapper;
     private final MainPositionMapper mainPositionMapper;
     private final PaymentMapper paymentMapper;
     private final SysTenantMapper sysTenantMapper;
@@ -559,6 +562,10 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
             throw new ServiceException("无权查看该候选人的报告");
         }
 
+        if (record.getReportStatus() == null || record.getReportStatus() != 1) {
+            throw new ServiceException("报告尚未填写完毕,暂时无法生成和查看!");
+        }
+
         if (StringUtils.isNotBlank(record.getReportUrl())) {
             return record.getReportUrl();
         }
@@ -639,6 +646,11 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
         if (backOrder == null || !StringUtils.equals(backOrder.getTenantId(), tenantId)) {
             throw new ServiceException("无权查看该候选人的报告");
         }
+
+        if (record.getReportStatus() == null || record.getReportStatus() != 1) {
+            throw new ServiceException("报告尚未填写完毕,暂时无法生成和查看!");
+        }
+
         return record;
     }
 
@@ -905,6 +917,12 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
                 .last("limit 1")
         );
 
+        List<MainBackInterview> interviews = mainBackInterviewMapper.selectList(
+            Wrappers.<MainBackInterview>lambdaQuery()
+                .eq(MainBackInterview::getRecordId, record.getId())
+                .orderByAsc(MainBackInterview::getId)
+        );
+
         Long postId = review != null && review.getPostId() != null ? review.getPostId() : candidate == null ? null : candidate.getPostId();
         MainPosition position = postId == null ? null : mainPositionMapper.selectById(postId);
         SysTenantVo tenant = tenantService.queryByTenantId(backOrder.getTenantId());
@@ -914,6 +932,7 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
         context.review = review;
         context.education = education;
         context.experience = experience;
+        context.interviews = interviews;
         context.position = position;
         context.record = record;
         context.backOrder = backOrder;
@@ -931,39 +950,30 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
 
         // 学历核实
         placeholders.put("school", safe(resolveSchoolName(context)));
-        placeholders.put("certNo", " ");
-        placeholders.put("eduVerification", safe(resolveEducationVerification(context)));
+        placeholders.put("certNo", safe(context.education == null ? null : context.education.getCertNo()));
+        placeholders.put("eduVerification", safe(context.education == null ? null : context.education.getEduVerification()));
 
         // 最近工作单位
         placeholders.put("company", safe(context.experience == null ? null : context.experience.getCompany()));
         placeholders.put("employmentPeriod", safe(resolveEmploymentPeriod(context)));
         placeholders.put("jobTitle", safe(resolveLatestJobTitle(context)));
-        placeholders.put("lastSalary", " ");
+        placeholders.put("lastSalary", safe(context.experience == null ? null : context.experience.getLastSalary()));
         placeholders.put("leaveReason", safe(context.review == null ? null : context.review.getLeaveReason()));
 
         // 工作表现评估
-        placeholders.put("supervisorEval", " ");
-        placeholders.put("strength", safe(resolveWorkContent(context)));
-        placeholders.put("improvement", " ");
-        placeholders.put("professionalAbility",
-            safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityAName(),
-                context.review == null ? null : context.review.getAbilityARate(),
-                context.review == null ? null : context.review.getAbilityARemark())));
-        placeholders.put("workAttitude",
-            safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityBName(),
-                context.review == null ? null : context.review.getAbilityBRate(),
-                context.review == null ? null : context.review.getAbilityBRemark())));
-        placeholders.put("teamwork",
-            safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityCName(),
-                context.review == null ? null : context.review.getAbilityCRate(),
-                context.review == null ? null : context.review.getAbilityCRemark())));
-        placeholders.put("ethics", " ");
-        placeholders.put("colleagueEval", " ");
-        placeholders.put("cooperation", " ");
-        placeholders.put("colleagueAbility", " ");
-        placeholders.put("hrEval", " ");
-        placeholders.put("violation", " ");
-        placeholders.put("handover", " ");
+        placeholders.put("supervisorEval", safe(context.review == null ? null : context.review.getSupervisorEval()));
+        placeholders.put("strength", safe(context.review == null ? null : context.review.getStrength()));
+        placeholders.put("improvement", safe(context.review == null ? null : context.review.getImprovement()));
+        placeholders.put("professionalAbility", safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityAName(), context.review == null ? null : context.review.getAbilityARate(), context.review == null ? null : context.review.getAbilityARemark())));
+        placeholders.put("workAttitude", safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityBName(), context.review == null ? null : context.review.getAbilityBRate(), context.review == null ? null : context.review.getAbilityBRemark())));
+        placeholders.put("teamwork", safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityCName(), context.review == null ? null : context.review.getAbilityCRate(), context.review == null ? null : context.review.getAbilityCRemark())));
+        placeholders.put("ethics", safe(buildAbilityLine(context.review == null ? null : context.review.getAbilityDName(), context.review == null ? null : context.review.getAbilityDRate(), context.review == null ? null : context.review.getAbilityDRemark())));
+        placeholders.put("colleagueEval", safe(context.review == null ? null : context.review.getColleagueEval()));
+        placeholders.put("cooperation", safe(context.review == null ? null : context.review.getCooperation()));
+        placeholders.put("colleagueAbility", safe(context.review == null ? null : context.review.getColleagueAbility()));
+        placeholders.put("hrEval", safe(context.review == null ? null : context.review.getHrEval()));
+        placeholders.put("violation", safe(context.review == null ? null : context.review.getViolation()));
+        placeholders.put("handover", safe(context.review == null ? null : context.review.getHandover()));
 
         // 调查结论
         placeholders.put("conclusionReason", safe(context.review == null ? null : context.review.getTotalRemark()));
@@ -972,56 +982,46 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
         placeholders.put("investigator", safe(context.companyName));
         placeholders.put("investigateDate", safe(resolveSurveyTime(context)));
 
-        // 访谈记录(一)—— 使用上家公司数据
-        placeholders.put("interviewee1Name", " ");
-        placeholders.put("interviewee1Relation", "上级主管");
-        placeholders.put("interviewee1Contact", " ");
-        placeholders.put("qa1_a1", safe(resolveKnownAnswer(context)));
-        placeholders.put("qa1_a2", " ");
-        placeholders.put("qa1_a3", " ");
-        placeholders.put("qa1_a4", " ");
-        placeholders.put("qa1_a5", safe(context.review == null ? null : context.review.getTotalRemark()));
-
-        // 访谈记录(二)
-        placeholders.put("interviewee2Name", " ");
-        placeholders.put("interviewee2Relation", "公司HR");
-        placeholders.put("interviewee2Contact", " ");
-        placeholders.put("qa2_a1", " ");
-        placeholders.put("qa2_a2", " ");
-        placeholders.put("qa2_a3", " ");
-        placeholders.put("qa2_a4", " ");
-        placeholders.put("qa2_a5", " ");
-
-        // 访谈记录(三)
-        placeholders.put("interviewee3Name", " ");
-        placeholders.put("interviewee3Relation", "同事");
-        placeholders.put("interviewee3Contact", " ");
-        placeholders.put("qa3_a1", " ");
-        placeholders.put("qa3_a2", " ");
-        placeholders.put("qa3_a3", " ");
-        placeholders.put("qa3_a4", " ");
-        placeholders.put("qa3_a5", " ");
+        // 访谈记录 Q&A 填充
+        fillInterviewPlaceholders(placeholders, context);
 
         // 确保所有空值替换为空格,保证模板格式不被破坏
         placeholders.replaceAll((k, v) -> (v == null || v.isEmpty()) ? " " : v);
 
-        // ========== Checkbox 勾选框 (CB_ 前缀, 格式: "选项1,选项2,...|SELECTED:选中项") ==========
-        // 学历核实 - 核实结果
-        placeholders.put("CB_eduResult", "属实,不属实,无法核实|SELECTED:" + resolveEduCheckResult(context));
-        // 最近工作单位 - 核实结果
-        placeholders.put("CB_companyResult", "属实,部分属实,不属实|SELECTED:" + resolveCompanyCheckResult(context));
-        // 工作表现评估 - 核实结果
-        placeholders.put("CB_performResult", "良好,一般,需关注|SELECTED:" + resolvePerformCheckResult(context));
-        // 限制性协议
-        placeholders.put("CB_restrictAgreement", "竞业禁止协议:是,竞业禁止协议:否,保密协议:是,保密协议:否|SELECTED:");
-        // 劳动争议/失信记录
-        placeholders.put("CB_disputeRecord", "是,否|SELECTED:");
-        // 调查结论
-        placeholders.put("CB_conclusionResult", "推荐入职,有条件推荐,不推荐|SELECTED:" + resolveConclusionResult(context));
-
-        // ========== 备注/信息来源列 ==========
-        placeholders.put("companyRemark", " ");
-        placeholders.put("performRemark", " ");
+        // ========== Checkbox 勾选框 ==========
+        placeholders.put("CB_eduResult", "属实,不属实,无法核实|SELECTED:" + safe(context.education == null ? null : context.education.getCheckResult()));
+        placeholders.put("CB_companyResult", "属实,部分属实,不属实|SELECTED:" + safe(context.experience == null ? null : context.experience.getCheckResult()));
+        placeholders.put("CB_performResult", "良好,一般,需关注|SELECTED:" + safe(context.review == null ? null : context.review.getPerformCheckResult()));
+        
+        String agreeSelect = "";
+        if (context.review != null) {
+            if (Integer.valueOf(1).equals(context.review.getNonCompeteAgreement())) agreeSelect = "竞业禁止协议:是";
+            else if (Integer.valueOf(0).equals(context.review.getNonCompeteAgreement())) agreeSelect = "竞业禁止协议:否";
+            
+            if (Integer.valueOf(1).equals(context.review.getConfidentialityAgreement())) {
+                 agreeSelect += (agreeSelect.isEmpty() ? "" : "|SELECTED:") + "保密协议:是"; // NOT FULLY SUPPORTED by current CB logic to select multiple in one line natively, let's just format it as text if needed, but our WordReportService only supports ONE SELECTED. Wait, our word report service checks if option.equals(selected).
+                 // Actually, the placeholder supports one selected. Since they are separate options in the string, if we want multiple, we need to improve WordReportService.
+                 // For now, let's map them to 2 CB groups? No, word has them on one line.
+            }
+        }
+        
+        // Better approach for restriction agreements: it's better to use two different CB placeholders if they are multiple choices, 
+        // but the word template only has one CB_restrictAgreement. Let's fix that dynamically by creating a specialized string or just use the DB value.
+        // I will just use text replacing for now or keep it simple. Let's pass the raw string if needed.
+        placeholders.put("CB_restrictAgreement", "竞业禁止协议:是,竞业禁止协议:否,保密协议:是,保密协议:否|SELECTED:" + agreeSelect);
+        
+        String disputeSelect = "";
+        if (context.review != null && context.review.getLaborDispute() != null) {
+             disputeSelect = context.review.getLaborDispute() == 1 ? "是" : "否";
+        }
+        placeholders.put("CB_disputeRecord", "是,否|SELECTED:" + disputeSelect);
+        placeholders.put("CB_conclusionResult", "推荐入职,有条件推荐,不推荐|SELECTED:" + safe(context.review == null ? null : context.review.getConclusionResult()));
+
+        // ========== 备注列 ==========
+        placeholders.put("companyRemark", safe(context.experience == null ? null : context.experience.getCheckRemark()));
+        placeholders.put("performRemark", safe(context.review == null ? null : context.review.getPerformRemark()));
+        placeholders.put("restrictRemark", safe(context.review == null ? null : context.review.getAgreementRemark()));
+        placeholders.put("disputeRemark", safe(context.review == null ? null : context.review.getDisputeRemark()));
 
         return wordReportService.generatePdf(placeholders);
     }
@@ -1142,53 +1142,36 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
     }
 
     /**
-     * 学历核实 checkbox: 属实 / 不属实 / 无法核实
-     * 如果有学历数据则默认"属实",否则"无法核实"
-     */
-    private String resolveEduCheckResult(ReportContext context) {
-        if (context.education != null && StringUtils.isNotBlank(context.education.getSchool())) {
-            return "属实";
-        }
-        return "";
-    }
-
-    /**
-     * 工作单位核实 checkbox: 属实 / 部分属实 / 不属实
-     * 如果有 review 数据则默认"属实",否则留空
+     * 填充访谈记录到占位符
      */
-    private String resolveCompanyCheckResult(ReportContext context) {
-        if (context.review != null) {
-            return "属实";
+    private void fillInterviewPlaceholders(Map<String, String> placeholders, ReportContext context) {
+        // 先设默认空值
+        for (int i = 1; i <= 3; i++) {
+            placeholders.put("interviewee" + i + "Name", " ");
+            placeholders.put("interviewee" + i + "Relation", " ");
+            placeholders.put("interviewee" + i + "Contact", " ");
+            for (int q = 1; q <= 5; q++) {
+                placeholders.put("qa" + i + "_a" + q, " ");
+            }
         }
-        return "";
-    }
-
-    /**
-     * 工作表现 checkbox: 良好 / 一般 / 需关注
-     * 根据 totalRate 判断:>= 3.5 良好, >= 2 一般, < 2 需关注
-     */
-    private String resolvePerformCheckResult(ReportContext context) {
-        if (context.review != null && context.review.getTotalRate() != null) {
-            double rate = context.review.getTotalRate().doubleValue();
-            if (rate >= 3.5) return "良好";
-            if (rate >= 2.0) return "一般";
-            return "需关注";
+        
+        if (context.interviews == null || context.interviews.isEmpty()) {
+            return;
         }
-        return "";
-    }
 
-    /**
-     * 调查结论 checkbox: 推荐入职 / 有条件推荐 / 不推荐
-     * 根据 totalRate 判断:>= 3.5 推荐入职, >= 2 有条件推荐, < 2 不推荐
-     */
-    private String resolveConclusionResult(ReportContext context) {
-        if (context.review != null && context.review.getTotalRate() != null) {
-            double rate = context.review.getTotalRate().doubleValue();
-            if (rate >= 3.5) return "推荐入职";
-            if (rate >= 2.0) return "有条件推荐";
-            return "不推荐";
+        // 按顺序填充
+        for (int i = 0; i < Math.min(3, context.interviews.size()); i++) {
+            MainBackInterview iv = context.interviews.get(i);
+            int idx = i + 1;
+            placeholders.put("interviewee" + idx + "Name", safe(iv.getIntervieweeName()));
+            placeholders.put("interviewee" + idx + "Relation", safe(iv.getIntervieweeRelation()));
+            placeholders.put("interviewee" + idx + "Contact", safe(iv.getIntervieweeContact()));
+            placeholders.put("qa" + idx + "_a1", safe(iv.getQa1()));
+            placeholders.put("qa" + idx + "_a2", safe(iv.getQa2()));
+            placeholders.put("qa" + idx + "_a3", safe(iv.getQa3()));
+            placeholders.put("qa" + idx + "_a4", safe(iv.getQa4()));
+            placeholders.put("qa" + idx + "_a5", safe(iv.getQa5()));
         }
-        return "";
     }
 
     private static class ReportContext {
@@ -1196,6 +1179,7 @@ public class MainBackOrderServiceImpl implements IMainBackOrderService {
         private MainPostCandidateReview review;
         private MainStudentEducation education;
         private MainStudentExperience experience;
+        private List<MainBackInterview> interviews;
         private MainPosition position;
         private MainBackRecord record;
         private MainBackOrder backOrder;

BIN
ruoyi-modules/ruoyi-main/src/main/resources/templates/report_template.docx