Gqingci 2 dní pred
rodič
commit
7c0d9f513a

+ 25 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/controller/MainBackRecordController.java

@@ -1,15 +1,22 @@
 package org.dromara.main.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
+import org.dromara.main.domain.bo.BackCheckReportSubmitBo;
 import org.dromara.main.domain.bo.MainBackRecordBo;
+import org.dromara.main.domain.vo.BackCheckReportVo;
 import org.dromara.main.domain.vo.MainBackRecordVo;
 import org.dromara.main.service.IMainBackRecordService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -36,4 +43,22 @@ public class MainBackRecordController extends BaseController {
             PageQuery pageQuery) {
         return mainBackRecordService.queryPageList(orderId, bo, pageQuery);
     }
+
+    /**
+     * 查询背调报告详情(表单数据+访谈记录)
+     */
+    @GetMapping("/{id}/report")
+    public R<BackCheckReportVo> getReport(@PathVariable Long id) {
+        return R.ok(mainBackRecordService.getBackCheckReport(id));
+    }
+
+    /**
+     * 管理端提交背调报告(需登录,含三个核实结果)
+     */
+    @SaCheckPermission("system:backRecord:edit")
+    @PutMapping("/{id}/report")
+    public R<Void> submitReport(@NotNull(message = "记录ID不能为空") @PathVariable Long id,
+                                @Validated @RequestBody BackCheckReportSubmitBo bo) {
+        return toAjax(mainBackRecordService.submitBackCheckReport(id, bo));
+    }
 }

+ 94 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/bo/BackCheckReportSubmitBo.java

@@ -0,0 +1,94 @@
+package org.dromara.main.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 管理端背调报告提交BO(需登录,含三个核实结果)
+ */
+@Data
+public class BackCheckReportSubmitBo {
+
+    // ===== 1. 候选人基本信息 =====
+    private String candidateName;
+    private String applyPosition;
+    private String checkTime;
+
+    // ===== 2. 学历核实 =====
+    private String gradSchool;
+    private String eduCertNo;
+    private String eduVerifyStatus;
+    /** 学历核实结果: 属实/不属实/无法核实 */
+    private String eduCheckResult;
+
+    // ===== 3. 最近工作单位 =====
+    private String companyName;
+    /** [开始日期, 结束日期] */
+    private List<String> workPeriod;
+    private String position;
+    private String lastSalary;
+    private String leaveReasonVerify;
+    /** 备注/信息来源 */
+    private String companyCheckRemark;
+    /** 工作单位核实结果: 属实/部分属实/不属实 */
+    private String companyCheckResult;
+
+    // ===== 4. 工作表现评估 - 上级评价 =====
+    private String leaderEvalAdvantage;
+    private String leaderEvalImprove;
+    private String leaderEvalProf;
+    private String leaderEvalAttitude;
+    private String leaderEvalTeam;
+    private String leaderEvalMorals;
+
+    // ===== 4. 工作表现评估 - 同事评价 =====
+    private String colleagueEvalTeamwork;
+    private String colleagueEvalProf;
+
+    // ===== 4. 工作表现评估 - HR评价 =====
+    private String hrEvalDispute;
+    private String hrEvalTransfer;
+    /** 备注/信息来源 */
+    private String performCheckRemark;
+    /** 表现核实结果: 良好/一般/需关注 */
+    private String performCheckResult;
+
+    // ===== 5. 法务风险 =====
+    private Boolean hasNonCompete;
+    private Boolean hasNda;
+    private String agreementRemark;
+    private Boolean hasDisputeStatus;
+    private String disputeRemark;
+
+    // ===== 6. 访谈记录 =====
+    private InterviewInfo interviewSupervisor;
+    private InterviewInfo interviewHR;
+    private InterviewInfo interviewColleague;
+
+    // ===== 7. 调查结论 =====
+    /** 推荐入职 / 有条件推荐 / 不推荐 */
+    private String conclusion;
+    private String conclusionReason;
+    private String investigatorName;
+    private String investigatorDate;
+
+    @Data
+    public static class InterviewInfo {
+        private String name;
+        private String relationship;
+        private String contact;
+        private String q1;
+        private String q2;
+        private String q3;
+        private String q4;
+        private String q5;
+
+        public boolean hasContent() {
+            return (name != null && !name.isBlank())
+                || (q1 != null && !q1.isBlank())
+                || (q2 != null && !q2.isBlank());
+        }
+    }
+}

+ 84 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/vo/BackCheckReportVo.java

@@ -0,0 +1,84 @@
+package org.dromara.main.domain.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 背调报告详情VO(含表单数据+访谈记录)
+ */
+@Data
+public class BackCheckReportVo {
+
+    // ===== 1. 候选人基本信息 =====
+    private String candidateName;
+    private String applyPosition;
+    private Date checkTime;
+
+    // ===== 2. 学历核实 =====
+    private String gradSchool;
+    private String eduCertNo;
+    private String eduVerifyStatus;
+    /** 学历核实结果: 属实/不属实/无法核实 */
+    private String eduCheckResult;
+
+    // ===== 3. 最近工作单位 =====
+    private String companyName;
+    private String workStartTime;
+    private String workEndTime;
+    private String jobTitle;
+    private String lastSalary;
+    private String leaveReasonVerify;
+    private String companyCheckRemark;
+    /** 工作单位核实结果: 属实/部分属实/不属实 */
+    private String companyCheckResult;
+
+    // ===== 4. 工作表现 - 上级 =====
+    private String leaderEvalAdvantage;
+    private String leaderEvalImprove;
+    private String leaderEvalProf;
+    private String leaderEvalAttitude;
+    private String leaderEvalTeam;
+    private String leaderEvalMorals;
+
+    // ===== 4. 工作表现 - 同事 =====
+    private String colleagueEvalTeamwork;
+    private String colleagueEvalProf;
+
+    // ===== 4. 工作表现 - HR =====
+    private String hrEvalDispute;
+    private String hrEvalTransfer;
+    private String performCheckRemark;
+    /** 表现核实结果: 良好/一般/需关注 */
+    private String performCheckResult;
+
+    // ===== 5. 法务风险 =====
+    private Integer hasNonCompete;
+    private Integer hasNda;
+    private String agreementRemark;
+    private Integer hasDispute;
+    private String disputeRemark;
+
+    // ===== 7. 调查结论 =====
+    private String conclusion;
+    private String conclusionReason;
+    private String investigatorName;
+    private Date investigatorDate;
+
+    // ===== 访谈记录列表 =====
+    private List<InterviewVo> interviews;
+
+    @Data
+    public static class InterviewVo {
+        private Long id;
+        private String intervieweeName;
+        private String intervieweeRelation;
+        private String intervieweeContact;
+        private String qa1;
+        private String qa2;
+        private String qa3;
+        private String qa4;
+        private String qa5;
+    }
+}

+ 12 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/IMainBackRecordService.java

@@ -2,7 +2,9 @@ package org.dromara.main.service;
 
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.main.domain.bo.BackCheckReportSubmitBo;
 import org.dromara.main.domain.bo.MainBackRecordBo;
+import org.dromara.main.domain.vo.BackCheckReportVo;
 import org.dromara.main.domain.vo.MainBackRecordVo;
 
 /**
@@ -14,4 +16,14 @@ public interface IMainBackRecordService {
      * 查询背调执行记录分页列表(候选人列表)
      */
     TableDataInfo<MainBackRecordVo> queryPageList(Long orderId, MainBackRecordBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询背调报告详情(表单数据+访谈记录)
+     */
+    BackCheckReportVo getBackCheckReport(Long recordId);
+
+    /**
+     * 管理端提交背调报告(含三个核实结果)
+     */
+    Boolean submitBackCheckReport(Long recordId, BackCheckReportSubmitBo bo);
 }

+ 187 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/impl/MainBackRecordServiceImpl.java

@@ -1,21 +1,38 @@
 package org.dromara.main.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.main.domain.MainBackCandidate;
+import org.dromara.main.domain.MainBackCheckData;
+import org.dromara.main.domain.MainBackInterview;
+import org.dromara.main.domain.MainBackOrder;
 import org.dromara.main.domain.MainBackRecord;
 import org.dromara.main.domain.MainStudent;
+import org.dromara.main.domain.bo.BackCheckReportSubmitBo;
 import org.dromara.main.domain.bo.MainBackRecordBo;
+import org.dromara.main.domain.vo.BackCheckReportVo;
 import org.dromara.main.domain.vo.MainBackRecordVo;
 import org.dromara.main.mapper.MainBackCandidateMapper;
+import org.dromara.main.mapper.MainBackCheckDataMapper;
+import org.dromara.main.mapper.MainBackInterviewMapper;
+import org.dromara.main.mapper.MainBackOrderMapper;
 import org.dromara.main.mapper.MainBackRecordMapper;
 import org.dromara.main.mapper.MainStudentMapper;
 import org.dromara.main.service.IMainBackRecordService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 背调执行记录Service业务层处理
@@ -27,6 +44,9 @@ public class MainBackRecordServiceImpl implements IMainBackRecordService {
     private final MainBackRecordMapper baseMapper;
     private final MainStudentMapper studentMapper;
     private final MainBackCandidateMapper candidateMapper;
+    private final MainBackCheckDataMapper checkDataMapper;
+    private final MainBackInterviewMapper interviewMapper;
+    private final MainBackOrderMapper backOrderMapper;
 
 
     @Override
@@ -65,4 +85,171 @@ public class MainBackRecordServiceImpl implements IMainBackRecordService {
 
         return result;
     }
+
+    @Override
+    public BackCheckReportVo getBackCheckReport(Long recordId) {
+        BackCheckReportVo vo = new BackCheckReportVo();
+
+        // 1. 查询表单数据
+        MainBackCheckData checkData = checkDataMapper.selectOne(
+            new LambdaQueryWrapper<MainBackCheckData>()
+                .eq(MainBackCheckData::getRecordId, recordId)
+                .last("limit 1")
+        );
+
+        if (checkData != null) {
+            BeanUtil.copyProperties(checkData, vo);
+        }
+
+        // 2. 查询访谈记录
+        List<MainBackInterview> interviews = interviewMapper.selectList(
+            new LambdaQueryWrapper<MainBackInterview>()
+                .eq(MainBackInterview::getRecordId, recordId)
+                .orderByAsc(MainBackInterview::getId)
+        );
+
+        List<BackCheckReportVo.InterviewVo> interviewVos = new ArrayList<>();
+        for (MainBackInterview interview : interviews) {
+            BackCheckReportVo.InterviewVo iv = new BackCheckReportVo.InterviewVo();
+            BeanUtil.copyProperties(interview, iv);
+            interviewVos.add(iv);
+        }
+        vo.setInterviews(interviewVos);
+
+        return vo;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean submitBackCheckReport(Long recordId, BackCheckReportSubmitBo bo) {
+        // 1. 校验 record 存在
+        MainBackRecord record = baseMapper.selectById(recordId);
+        if (record == null) {
+            throw new ServiceException("背调记录不存在");
+        }
+
+        // 2. 校验候选人
+        MainBackCandidate candidate = candidateMapper.selectById(record.getCandidateId());
+        if (candidate == null) {
+            throw new ServiceException("候选人记录不存在");
+        }
+
+        // 3. 组装 MainBackCheckData 并保存
+        MainBackCheckData checkData = new MainBackCheckData();
+        checkData.setRecordId(recordId);
+        checkData.setCandidateId(candidate.getId());
+        MainBackOrder backOrder = backOrderMapper.selectById(record.getOrderId());
+        checkData.setTenantId(backOrder == null ? null : backOrder.getTenantId());
+
+        // 候选人基本信息
+        checkData.setCandidateName(bo.getCandidateName());
+        checkData.setApplyPosition(bo.getApplyPosition());
+        if (StringUtils.isNotBlank(bo.getCheckTime())) {
+            try {
+                checkData.setCheckTime(new java.text.SimpleDateFormat("yyyy-MM-dd").parse(bo.getCheckTime()));
+            } catch (Exception ignored) {}
+        }
+
+        // 学历核实(含核实结果)
+        checkData.setGradSchool(bo.getGradSchool());
+        checkData.setEduCertNo(bo.getEduCertNo());
+        checkData.setEduVerifyStatus(bo.getEduVerifyStatus());
+        checkData.setEduCheckResult(bo.getEduCheckResult());
+
+        // 最近工作单位(含核实结果)
+        checkData.setCompanyName(bo.getCompanyName());
+        if (bo.getWorkPeriod() != null && bo.getWorkPeriod().size() >= 2) {
+            checkData.setWorkStartTime(bo.getWorkPeriod().get(0));
+            checkData.setWorkEndTime(bo.getWorkPeriod().get(1));
+        }
+        checkData.setJobTitle(bo.getPosition());
+        checkData.setLastSalary(bo.getLastSalary());
+        checkData.setLeaveReasonVerify(bo.getLeaveReasonVerify());
+        checkData.setCompanyCheckRemark(bo.getCompanyCheckRemark());
+        checkData.setCompanyCheckResult(bo.getCompanyCheckResult());
+
+        // 工作表现 - 上级
+        checkData.setLeaderEvalAdvantage(bo.getLeaderEvalAdvantage());
+        checkData.setLeaderEvalImprove(bo.getLeaderEvalImprove());
+        checkData.setLeaderEvalProf(bo.getLeaderEvalProf());
+        checkData.setLeaderEvalAttitude(bo.getLeaderEvalAttitude());
+        checkData.setLeaderEvalTeam(bo.getLeaderEvalTeam());
+        checkData.setLeaderEvalMorals(bo.getLeaderEvalMorals());
+
+        // 工作表现 - 同事
+        checkData.setColleagueEvalTeamwork(bo.getColleagueEvalTeamwork());
+        checkData.setColleagueEvalProf(bo.getColleagueEvalProf());
+
+        // 工作表现 - HR(含核实结果)
+        checkData.setHrEvalDispute(bo.getHrEvalDispute());
+        checkData.setHrEvalTransfer(bo.getHrEvalTransfer());
+        checkData.setPerformCheckRemark(bo.getPerformCheckRemark());
+        checkData.setPerformCheckResult(bo.getPerformCheckResult());
+
+        // 法务风险
+        checkData.setHasNonCompete(bo.getHasNonCompete() != null && bo.getHasNonCompete() ? 1 : 0);
+        checkData.setHasNda(bo.getHasNda() != null && bo.getHasNda() ? 1 : 0);
+        checkData.setAgreementRemark(bo.getAgreementRemark());
+        checkData.setHasDispute(bo.getHasDisputeStatus() != null && bo.getHasDisputeStatus() ? 1 : 0);
+        checkData.setDisputeRemark(bo.getDisputeRemark());
+
+        // 调查结论
+        checkData.setConclusion(bo.getConclusion());
+        checkData.setConclusionReason(bo.getConclusionReason());
+        checkData.setInvestigatorName(bo.getInvestigatorName());
+        if (StringUtils.isNotBlank(bo.getInvestigatorDate())) {
+            try {
+                checkData.setInvestigatorDate(new java.text.SimpleDateFormat("yyyy-MM-dd").parse(bo.getInvestigatorDate()));
+            } catch (Exception ignored) {}
+        }
+
+        // saveOrUpdate(按recordId去重)
+        MainBackCheckData existing = checkDataMapper.selectOne(
+            new LambdaQueryWrapper<MainBackCheckData>()
+                .eq(MainBackCheckData::getRecordId, recordId)
+                .last("limit 1")
+        );
+        if (existing == null) {
+            checkDataMapper.insert(checkData);
+        } else {
+            checkData.setId(existing.getId());
+            checkDataMapper.updateById(checkData);
+        }
+
+        // 4. 保存访谈记录(先删旧的,再插入新的)
+        interviewMapper.delete(
+            Wrappers.<MainBackInterview>lambdaQuery()
+                .eq(MainBackInterview::getRecordId, recordId)
+        );
+        BackCheckReportSubmitBo.InterviewInfo[] interviews = {
+            bo.getInterviewSupervisor(), bo.getInterviewHR(), bo.getInterviewColleague()
+        };
+        for (BackCheckReportSubmitBo.InterviewInfo info : interviews) {
+            if (info != null && info.hasContent()) {
+                MainBackInterview interview = new MainBackInterview();
+                interview.setCandidateId(candidate.getId());
+                interview.setRecordId(recordId);
+                interview.setIntervieweeName(info.getName());
+                interview.setIntervieweeRelation(info.getRelationship());
+                interview.setIntervieweeContact(info.getContact());
+                interview.setQa1(info.getQ1());
+                interview.setQa2(info.getQ2());
+                interview.setQa3(info.getQ3());
+                interview.setQa4(info.getQ4());
+                interview.setQa5(info.getQ5());
+                interview.setTenantId(backOrder == null ? null : backOrder.getTenantId());
+                interviewMapper.insert(interview);
+            }
+        }
+
+        // 5. 更新 record 状态为 2(已提交)
+        MainBackRecord update = new MainBackRecord();
+        update.setId(recordId);
+        update.setReportStatus(2);
+        update.setReportUrl(null);
+        update.setFinishTime(LocalDateTime.now());
+        baseMapper.updateById(update);
+
+        return true;
+    }
 }