From a3cd9b02771741303f81e372667a0ca994c756f7 Mon Sep 17 00:00:00 2001 From: francis-fh Date: Wed, 24 Jun 2026 09:31:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=9D=A2=E8=AF=95=E9=82=80?= =?UTF-8?q?=E7=BA=A6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/AppInterviewController.java | 62 ++++++++++ .../cms/CmsInterviewController.java | 80 ++++++++++++ .../ruoyi/cms/domain/InterviewInvitation.java | 85 +++++++++++++ .../cms/mapper/InterviewInvitationMapper.java | 9 ++ .../service/InterviewInvitationService.java | 27 ++++ .../impl/InterviewInvitationServiceImpl.java | 115 ++++++++++++++++++ .../mapper/app/InterviewInvitationMapper.xml | 48 ++++++++ sql/interview_invitation.sql | 35 ++++++ 8 files changed, 461 insertions(+) create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppInterviewController.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsInterviewController.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/InterviewInvitation.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/InterviewInvitationMapper.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/InterviewInvitationService.java create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/InterviewInvitationServiceImpl.java create mode 100644 ruoyi-bussiness/src/main/resources/mapper/app/InterviewInvitationMapper.xml create mode 100644 sql/interview_invitation.sql diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppInterviewController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppInterviewController.java new file mode 100644 index 0000000..cc30d35 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppInterviewController.java @@ -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 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)); + } +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsInterviewController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsInterviewController.java new file mode 100644 index 0000000..27239ff --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsInterviewController.java @@ -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 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)); + } +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/InterviewInvitation.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/InterviewInvitation.java new file mode 100644 index 0000000..7504d52 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/InterviewInvitation.java @@ -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; +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/InterviewInvitationMapper.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/InterviewInvitationMapper.java new file mode 100644 index 0000000..2bbe6d1 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/InterviewInvitationMapper.java @@ -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 { + List getInterviewInvitationList(InterviewInvitation interviewInvitation); +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/InterviewInvitationService.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/InterviewInvitationService.java new file mode 100644 index 0000000..1d15580 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/InterviewInvitationService.java @@ -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 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); +} diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/InterviewInvitationServiceImpl.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/InterviewInvitationServiceImpl.java new file mode 100644 index 0000000..4f28c50 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/InterviewInvitationServiceImpl.java @@ -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 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; + } +} diff --git a/ruoyi-bussiness/src/main/resources/mapper/app/InterviewInvitationMapper.xml b/ruoyi-bussiness/src/main/resources/mapper/app/InterviewInvitationMapper.xml new file mode 100644 index 0000000..d745909 --- /dev/null +++ b/ruoyi-bussiness/src/main/resources/mapper/app/InterviewInvitationMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, company_id, job_id, user_id, apply_id, interview_time, + interview_method, meeting_link, meeting_password, interview_location, + contact_phone, status, del_flag, create_by, create_time, update_by, update_time, remark + from interview_invitation + + + + + diff --git a/sql/interview_invitation.sql b/sql/interview_invitation.sql new file mode 100644 index 0000000..189253e --- /dev/null +++ b/sql/interview_invitation.sql @@ -0,0 +1,35 @@ +-- 面试邀约表 +create table "interview_invitation" +( + "id" bigint not null, + "company_id" bigint not null, + "job_id" bigint not null, + "user_id" bigint not null, + "apply_id" bigint null, + "interview_time" varchar(100) null, + "interview_method" varchar(20) null, + "meeting_link" varchar(500) null, + "meeting_password" varchar(100) null, + "interview_location" varchar(500) null, + "contact_phone" varchar(50) null, + "status" varchar(20) default 'pending' null, + "del_flag" char(1) default '0' null, + "create_by" varchar(64) default '' null, + "create_time" timestamp(0) null, + "update_by" varchar(64) default '' null, + "update_time" timestamp(0) null, + "remark" varchar(500) null +); + +comment on table "interview_invitation" is '面试邀约表'; +comment on column "interview_invitation"."id" is '主键id'; +comment on column "interview_invitation"."company_id" is '企业id'; +comment on column "interview_invitation"."job_id" is '岗位id'; +comment on column "interview_invitation"."user_id" is '用户id'; +comment on column "interview_invitation"."apply_id" is '申请id'; +comment on column "interview_invitation"."interview_time" is '面试时间'; +comment on column "interview_invitation"."interview_method" is '面试方式(online/offline)'; +comment on column "interview_invitation"."meeting_link" is '腾讯会议链接'; +comment on column "interview_invitation"."meeting_password" is '会议密码'; +comment on column "interview_invitation"."interview_location" is '面试地点'; +comment on column "interview_invitation"."status" is '状态(pending/accepted/rejected/completed)';