新增面试邀约功能

This commit is contained in:
francis-fh
2026-06-24 09:31:29 +08:00
parent 7d5ad10883
commit a3cd9b0277
8 changed files with 461 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
package com.ruoyi.cms.controller.app;
import com.ruoyi.cms.domain.InterviewInvitation;
import com.ruoyi.cms.service.InterviewInvitationService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.SiteSecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 移动端:面试邀约
*
* @author
* @email
* @date 2025-10-10 10:42:16
*/
@RestController
@RequestMapping("/app/interview")
@Api(tags = "移动端:面试邀约")
public class AppInterviewController extends BaseController {
@Autowired
private InterviewInvitationService interviewInvitationService;
/**
* 我的面试邀约列表
*/
@ApiOperation("我的面试邀约列表")
@GetMapping("/list")
public TableDataInfo list(){
InterviewInvitation query = new InterviewInvitation();
query.setUserId(SiteSecurityUtils.getUserId());
startPage();
List<InterviewInvitation> list = interviewInvitationService.getInterviewInvitationList(query);
return getDataTable(list);
}
/**
* 获取详细信息
*/
@ApiOperation("面试邀约详情")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id){
return AjaxResult.success(interviewInvitationService.getInterviewInvitationById(id));
}
/**
* 更新面试邀约状态(接受/拒绝)
*/
@ApiOperation("更新面试邀约状态")
@PutMapping("/status/{id}")
public AjaxResult updateStatus(@PathVariable Long id, @RequestParam String status){
return toAjax(interviewInvitationService.updateInterviewStatus(id, status));
}
}

View File

@@ -0,0 +1,80 @@
package com.ruoyi.cms.controller.cms;
import com.ruoyi.cms.domain.InterviewInvitation;
import com.ruoyi.cms.service.InterviewInvitationService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 面试邀约
*
* @author
* @email
* @date 2025-10-10 10:42:16
*/
@RestController
@RequestMapping("/cms/interview")
@Api(tags = "后台:面试邀约")
public class CmsInterviewController extends BaseController {
@Autowired
private InterviewInvitationService interviewInvitationService;
/**
* 列表
*/
@ApiOperation("面试邀约列表")
@PreAuthorize("@ss.hasPermi('cms:interview:list')")
@GetMapping("/list")
public TableDataInfo list(InterviewInvitation interviewInvitation){
startPage();
List<InterviewInvitation> list = interviewInvitationService.getInterviewInvitationList(interviewInvitation);
return getDataTable(list);
}
/**
* 保存
*/
@ApiOperation("新增面试邀约")
@PreAuthorize("@ss.hasPermi('cms:interview:add')")
@Log(title = "面试邀约", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InterviewInvitation interviewInvitation){
return toAjax(interviewInvitationService.insertInterviewInvitation(interviewInvitation));
}
@ApiOperation("修改面试邀约")
@PreAuthorize("@ss.hasPermi('cms:interview:edit')")
@Log(title = "面试邀约", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InterviewInvitation interviewInvitation){
return toAjax(interviewInvitationService.updateInterviewInvitation(interviewInvitation));
}
@ApiOperation("删除面试邀约")
@PreAuthorize("@ss.hasPermi('cms:interview:remove')")
@Log(title = "面试邀约", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(interviewInvitationService.deleteInterviewInvitationIds(ids));
}
@ApiOperation("面试邀约详情")
@PreAuthorize("@ss.hasPermi('cms:interview:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id)
{
return AjaxResult.success(interviewInvitationService.getInterviewInvitationById(id));
}
}

View File

@@ -0,0 +1,85 @@
package com.ruoyi.cms.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 面试邀约
*
* @author
* @email
* @date 2025-10-10 10:42:16
*/
@Data
@TableName("interview_invitation")
public class InterviewInvitation extends BaseEntity {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id",type = IdType.AUTO)
@ApiModelProperty("id")
private Long id;
/**
* 企业id
*/
@ApiModelProperty("企业id")
private Long companyId;
/**
* 岗位id
*/
@ApiModelProperty("岗位id")
private Long jobId;
/**
* 用户id
*/
@ApiModelProperty("用户id")
private Long userId;
/**
* 申请id
*/
@ApiModelProperty("申请id")
private Long applyId;
/**
* 面试时间
*/
@ApiModelProperty("面试时间")
private String interviewTime;
/**
* 面试方式(online/offline)
*/
@ApiModelProperty("面试方式")
private String interviewMethod;
/**
* 腾讯会议链接
*/
@ApiModelProperty("腾讯会议链接")
private String meetingLink;
/**
* 会议密码
*/
@ApiModelProperty("会议密码")
private String meetingPassword;
/**
* 面试地点
*/
@ApiModelProperty("面试地点")
private String interviewLocation;
/**
* 面试官联系方式
*/
@ApiModelProperty("面试官联系方式")
private String contactPhone;
/**
* 状态(pending/accepted/rejected/completed)
*/
@ApiModelProperty("状态")
private String status;
}

View File

@@ -0,0 +1,9 @@
package com.ruoyi.cms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.cms.domain.InterviewInvitation;
import java.util.List;
public interface InterviewInvitationMapper extends BaseMapper<InterviewInvitation> {
List<InterviewInvitation> getInterviewInvitationList(InterviewInvitation interviewInvitation);
}

View File

@@ -0,0 +1,27 @@
package com.ruoyi.cms.service;
import com.ruoyi.cms.domain.InterviewInvitation;
import java.util.List;
/**
* 面试邀约
*
* @author
* @email
* @date 2025-10-10 10:42:16
*/
public interface InterviewInvitationService {
List<InterviewInvitation> getInterviewInvitationList(InterviewInvitation interviewInvitation);
int insertInterviewInvitation(InterviewInvitation interviewInvitation);
int updateInterviewInvitation(InterviewInvitation interviewInvitation);
int deleteInterviewInvitationIds(Long[] ids);
InterviewInvitation getInterviewInvitationById(Long id);
int updateInterviewStatus(Long id, String status);
}

View File

@@ -0,0 +1,115 @@
package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.domain.InterviewInvitation;
import com.ruoyi.cms.domain.Job;
import com.ruoyi.cms.domain.JobApply;
import com.ruoyi.cms.domain.Notice;
import com.ruoyi.cms.mapper.InterviewInvitationMapper;
import com.ruoyi.cms.mapper.JobApplyMapper;
import com.ruoyi.cms.mapper.JobMapper;
import com.ruoyi.cms.mapper.NoticeMapper;
import com.ruoyi.cms.service.InterviewInvitationService;
import com.ruoyi.cms.util.notice.NoticeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class InterviewInvitationServiceImpl implements InterviewInvitationService {
@Autowired
InterviewInvitationMapper interviewInvitationMapper;
@Autowired
private JobApplyMapper jobApplyMapper;
@Autowired
private NoticeMapper noticeMapper;
@Autowired
private JobMapper jobMapper;
@Override
public List<InterviewInvitation> getInterviewInvitationList(InterviewInvitation interviewInvitation) {
return interviewInvitationMapper.getInterviewInvitationList(interviewInvitation);
}
@Override
public int insertInterviewInvitation(InterviewInvitation interviewInvitation) {
int t = interviewInvitationMapper.insert(interviewInvitation);
if (t > 0) {
// 获取岗位和申请信息
Job job = jobMapper.getJobInfo(interviewInvitation.getJobId());
JobApply jobApply = jobApplyMapper.selectById(interviewInvitation.getApplyId());
// 创建面试邀约通知
Notice notice = createInterviewNotice(interviewInvitation, job, jobApply);
if (notice != null) {
noticeMapper.insert(notice);
}
}
return t;
}
@Override
public int updateInterviewInvitation(InterviewInvitation interviewInvitation) {
return interviewInvitationMapper.updateById(interviewInvitation);
}
@Override
public int deleteInterviewInvitationIds(Long[] ids) {
return interviewInvitationMapper.deleteBatchIds(Arrays.asList(ids));
}
@Override
public InterviewInvitation getInterviewInvitationById(Long id) {
return interviewInvitationMapper.selectById(id);
}
@Override
public int updateInterviewStatus(Long id, String status) {
InterviewInvitation invitation = new InterviewInvitation();
invitation.setId(id);
invitation.setStatus(status);
return interviewInvitationMapper.updateById(invitation);
}
/**
* 创建面试邀约通知
*/
private Notice createInterviewNotice(InterviewInvitation invitation, Job job, JobApply jobApply) {
Notice notice = new Notice();
Long userId = invitation.getUserId();
if (userId == null && jobApply != null) {
userId = jobApply.getUserId();
}
notice.setUserId(userId);
notice.setBussinessId(invitation.getJobId());
notice.setIsRead(NoticeUtils.NOTICE_WD);
notice.setTitle("面试邀约通知");
notice.setSubTitle("面试邀约");
notice.setNoticeType(NoticeUtils.NOTICE_TYPE_XTLX);
notice.setRemark(NoticeUtils.NOTICE_REMARK);
// 拼装通知内容
String jobTitle = job != null ? job.getJobTitle() : "";
String methodText = "online".equals(invitation.getInterviewMethod()) ? "线上" : "线下";
StringBuilder content = new StringBuilder();
content.append("您好,您申请的【").append(jobTitle).append("】岗位收到了面试邀约。");
content.append("面试时间:").append(invitation.getInterviewTime() != null ? invitation.getInterviewTime() : "待定").append("");
content.append("面试方式:").append(methodText);
if ("online".equals(invitation.getInterviewMethod())) {
content.append(",腾讯会议链接:").append(invitation.getMeetingLink() != null ? invitation.getMeetingLink() : "");
content.append(",会议密码:").append(invitation.getMeetingPassword() != null ? invitation.getMeetingPassword() : "");
} else {
content.append(",面试地点:").append(invitation.getInterviewLocation() != null ? invitation.getInterviewLocation() : "");
}
if (invitation.getContactPhone() != null && !invitation.getContactPhone().isEmpty()) {
content.append(",面试官联系方式:").append(invitation.getContactPhone());
}
if (invitation.getRemark() != null && !invitation.getRemark().isEmpty()) {
content.append("。备注:").append(invitation.getRemark());
}
notice.setNoticeContent(content.toString());
return notice;
}
}