diff --git a/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java b/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java index 22035bed8..43394fa40 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java @@ -257,4 +257,10 @@ public class RedisConstant { * 动态标题 */ public static final String CONTENT_TITLES = "content:titles"; + + /** + * 用户预约面试锁 + */ + public static final String PARTNER_APPOINTMENT_LOCK = "partner:appointment:lock:{0}"; + } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/InterviewService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/InterviewService.java index 7ec194c28..66009c093 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/InterviewService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/InterviewService.java @@ -52,13 +52,6 @@ public interface InterviewService { */ EnterInterviewVO enterInterviewRoom(EnterInterviewDto dto) throws ApiException; - /** - * 创建面试预约信息 - * @param request - * @return - */ - CreateAppointmentVO createAppointment(CreateAppointmentReq request) throws ApiException; - /** * 同意面试预约 * @param request diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/PartnerInterviewService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/PartnerInterviewService.java index e196ecba5..b11663003 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/PartnerInterviewService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/PartnerInterviewService.java @@ -3,11 +3,13 @@ package com.cool.store.service; import com.cool.store.dto.partner.EnterInterviewDto; import com.cool.store.dto.partner.LineQueryInterviewDto; import com.cool.store.exception.ApiException; +import com.cool.store.request.CreateAppointmentReq; import com.cool.store.request.GetFreeBusyListReq; import com.cool.store.request.ModifyInterviewTimeReq; import com.cool.store.vo.EnterInterviewVO; import com.cool.store.vo.PartnerInterviewInfoVO; import com.cool.store.vo.PartnerPassLetterDetailVO; +import com.cool.store.vo.interview.CreateAppointmentVO; import com.cool.store.vo.interview.GetFreeBusyListVO; public interface PartnerInterviewService { @@ -47,4 +49,11 @@ public interface PartnerInterviewService { * @return {@link GetFreeBusyListVO} */ GetFreeBusyListVO getFreeBusyList(GetFreeBusyListReq request); + + /** + * 预约面试方法 + * @param request + * @return + */ + CreateAppointmentVO createAppointment(CreateAppointmentReq request) throws ApiException; } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/InterviewServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/InterviewServiceImpl.java index 1fd36aed7..0cfa79e1a 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/InterviewServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/InterviewServiceImpl.java @@ -7,7 +7,6 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import com.cool.store.context.CurrentUserHolder; import com.cool.store.context.LoginUserInfo; -import com.cool.store.context.PartnerUserHolder; import com.cool.store.dao.EnterpriseUserDAO; import com.cool.store.dao.HyIntendDevMappingDAO; import com.cool.store.dao.HyInterviewDAO; @@ -22,7 +21,6 @@ import com.cool.store.enums.*; import com.cool.store.exception.ApiException; import com.cool.store.exception.ServiceException; import com.cool.store.http.EventCenterHttpRequest; -import com.cool.store.http.ISVHttpRequest; import com.cool.store.mapper.HyPartnerBaseInfoMapper; import com.cool.store.mapper.HyPartnerInterviewMapper; import com.cool.store.mapper.HyPartnerInterviewPlanMapper; @@ -37,7 +35,6 @@ import com.cool.store.utils.StringUtil; import com.cool.store.utils.TRTCUtils; import com.cool.store.vo.EnterInterviewVO; import com.cool.store.vo.EnterpriseUserBaseInfoVO; -import com.cool.store.vo.PartnerUserInfoVO; import com.cool.store.vo.interview.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -66,21 +63,12 @@ public class InterviewServiceImpl implements InterviewService { @Value("${trtc.secretKey:null}") private String key; - @Value("${hs.sms.templateCode:null}") - private String templateCode; - - @Value("${feishu.notice.link.url}") - private String linkUrl; - @Autowired private HyPartnerInterviewPlanMapper hyPartnerInterviewPlanMapper; @Autowired private HyPartnerInterviewMapper hyPartnerInterviewMapper; - @Autowired - private ISVHttpRequest isvHttpRequest; - @Autowired private HyPartnerLineInfoMapper hyPartnerLineInfoMapper; @@ -95,8 +83,6 @@ public class InterviewServiceImpl implements InterviewService { @Autowired private EnterpriseUserService enterpriseUserService; -// @Autowired -// private SmsService smsService; @Autowired private HyInterviewDAO interviewDAO; @@ -489,98 +475,6 @@ public class InterviewServiceImpl implements InterviewService { } } - @Override - @Transactional - public CreateAppointmentVO createAppointment(CreateAppointmentReq request) throws ApiException { - if(request.getPartnerLineId() == null || request.getPartnerLineId()<=0){ - throw new ApiException(ErrorCodeEnum.INTERVIEW_LINE_ID_IS_NULL); - } - //如果开始时间小于当前时间需要报错 -// if(DateUtil.date().isAfter(DateUtil.parse(request.getStartBookingTime()))){ -// throw new ApiException(ErrorCodeEnum.CREATE_APPOINTMENT_TIME_ERROR); -// } - HyPartnerInterviewPlanDO hyPartnerInterviewPlanDO = new HyPartnerInterviewPlanDO(); - hyPartnerInterviewPlanDO.setPartnerLineId(request.getPartnerLineId()); - hyPartnerInterviewPlanDO.setDeleted(false); - List hyPartnerInterviewPlanDOS = hyPartnerInterviewPlanMapper.selectBySelective(hyPartnerInterviewPlanDO); - if(CollectionUtils.isNotEmpty(hyPartnerInterviewPlanDOS)&&hyPartnerInterviewPlanDOS.get(0).getId()!=null){ - throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_ALREADY_EXIST); - } - String interviewrId = request.getInterviewerId(); - if(StringUtils.isEmpty(interviewrId)){ - interviewrId = getInterviewerByPartner(request.getPartnerId(),String.valueOf(request.getPartnerLineId())); - } - CreateAppointmentVO vo = new CreateAppointmentVO(); - //1.创建面试计划 - HyPartnerInterviewPlanDO record = new HyPartnerInterviewPlanDO(); - String startBookingTime = request.getStartBookingTime(); - String startDate = startBookingTime.substring(0, 10); - record.setInterviewDate(Convert.toDate(startDate)); - record.setCreateTime(new Date()); - record.setUpdateTime(new Date()); - record.setStartTime(Convert.toDate(request.getStartBookingTime())); - record.setEndTime(Convert.toDate(request.getEndBookingTime())); - record.setPartnerId(request.getPartnerId()); - record.setPartnerLineId(request.getPartnerLineId()); - record.setInterviewer(interviewrId); - record.setIsPartnerInterview(0); - //生成房间号 - record.setRoomId(StringUtil.generateRoomId(startBookingTime)); - record.setRoomStatus(RoomStatus.WAIT_FOR_OPEN.getCode()); - record.setDeleted(false); - record.setApplicationApproved(0); - hyPartnerInterviewPlanMapper.insertSelective(record); - - List interviewPlanDOS = hyPartnerInterviewPlanMapper.selectBySelective(hyPartnerInterviewPlanDO); - if(CollectionUtils.isEmpty(interviewPlanDOS)){ - throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_NOT_EXIST); - } - Long interviewPlanId = interviewPlanDOS.get(0).getId(); - vo.setInterviewPlanId(String.valueOf(interviewPlanId)); - - //2.创建面试信息 - HyPartnerInterviewDO hyPartnerInterviewDO = new HyPartnerInterviewDO(); - hyPartnerInterviewDO.setInterviewPlanId(interviewPlanId); - hyPartnerInterviewDO.setPartnerLineId(request.getPartnerLineId()); - hyPartnerInterviewDO.setPartnerId(request.getPartnerId()); - hyPartnerInterviewDO.setInterviewer(interviewrId); - hyPartnerInterviewDO.setCreateTime(new Date()); - hyPartnerInterviewDO.setUpdateTime(new Date()); - hyPartnerInterviewDO.setStatus(Integer.valueOf(WorkflowStatusEnum.RESERVATION_1.getCode())); - hyPartnerInterviewDO.setDeleted(false); - hyPartnerInterviewMapper.insertSelective(hyPartnerInterviewDO); - - //修改线索状态 - HyPartnerLineInfoDO hyPartnerLineDO = new HyPartnerLineInfoDO(); - hyPartnerLineDO.setId(request.getPartnerLineId()); - hyPartnerLineDO.setWorkflowStatus(WorkflowStatusEnum.RESERVATION_1.getCode()); - hyPartnerLineDO.setUpdateTime(new Date()); - hyPartnerLineInfoMapper.updateByPrimaryKeySelective(hyPartnerLineDO); - - //异步发送飞书信息给面试官 - InterviewVO interviewVO = hyPartnerInterviewPlanMapper.getInterviewInfo(String.valueOf(interviewPlanId)); - List userIds = new ArrayList<>(); - userIds.add(interviewrId); - Map feishuUserIdsByUserIds = enterpriseUserDAO.getFeishuUserIdsByUserIds(userIds); -// SendCardMessageDTO sendCardMessageDTO = new SendCardMessageDTO(); -// sendCardMessageDTO.setUserIds(userIds); -// sendCardMessageDTO.setMessageType(FeiShuNoticeMsgEnum.INTERVIEW_APPOINTMENT); -// sendCardMessageDTO.setMessageUrl(linkUrl); -// sendCardMessageDTO.setTitle("面试预约申请"); -// sendCardMessageDTO.setContent(generateFeiShuInterviewMsg(interviewVO.getPartnerName(), interviewVO.getPartnerMobile(), interviewVO.getStartTime())); - //替换为通过事件中心发送消息 - eventCenterHttpRequest.sendFeiShuNotice(FeiShuNoticeMsgEnum.INTERVIEW_APPOINTMENT, - Arrays.asList(feishuUserIdsByUserIds.get(interviewrId)), - interviewVO.getPartnerName(), interviewVO.getPartnerMobile(), interviewVO.getStartTime()); - - //记录日志 - PartnerUserInfoVO operator = PartnerUserHolder.getUser(); - LogBasicDTO log = LogBasicDTO.builder().mobile(operator.getMobile()).operateUserId(operator.getPartnerId()).operateUsername(operator.getUsername()).operateTime(DateUtil.format(new Date(), CoolDateUtils.DATE_FORMAT_SEC)).mobile(operator.getMobile()).build(); - logService.recordPartnerBizLog(operator,interviewVO.getPartnerLineId(),OperateTypeEnum.INTERVIEW_APPOINTMENT,log); - - return vo; - } - @Override @Transactional public void approveAppointment(ApproveAppointmentReq request) throws ApiException { diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PartnerInterviewServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PartnerInterviewServiceImpl.java index 61c3e7f57..aac327f99 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PartnerInterviewServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/PartnerInterviewServiceImpl.java @@ -3,35 +3,39 @@ package com.cool.store.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; +import com.cool.store.constants.RedisConstant; import com.cool.store.context.PartnerUserHolder; +import com.cool.store.dao.EnterpriseUserDAO; import com.cool.store.dao.HyInterviewDAO; +import com.cool.store.dto.log.LogBasicDTO; import com.cool.store.dto.log.ModifyInterviewTimeDTO; import com.cool.store.dto.partner.EnterInterviewDto; import com.cool.store.dto.partner.LineQueryInterviewDto; -import com.cool.store.entity.HyPartnerInterviewBookSituation; import com.cool.store.entity.HyPartnerInterviewDO; import com.cool.store.entity.HyPartnerInterviewPlanDO; -import com.cool.store.enums.ErrorCodeEnum; -import com.cool.store.enums.OperateTypeEnum; -import com.cool.store.enums.RoomStatus; -import com.cool.store.enums.WorkflowStatusEnum; +import com.cool.store.entity.HyPartnerLineInfoDO; +import com.cool.store.enums.*; import com.cool.store.exception.ApiException; import com.cool.store.exception.ServiceException; +import com.cool.store.http.EventCenterHttpRequest; import com.cool.store.mapper.HyPartnerInterviewMapper; import com.cool.store.mapper.HyPartnerInterviewPlanMapper; +import com.cool.store.mapper.HyPartnerLineInfoMapper; +import com.cool.store.request.CreateAppointmentReq; import com.cool.store.request.GetFreeBusyListReq; import com.cool.store.request.ModifyInterviewTimeReq; import com.cool.store.service.InterviewService; import com.cool.store.service.LogService; import com.cool.store.service.PartnerInterviewService; import com.cool.store.utils.CoolDateUtils; +import com.cool.store.utils.RedisUtilPool; +import com.cool.store.utils.StringUtil; import com.cool.store.utils.TRTCUtils; import com.cool.store.vo.EnterInterviewVO; import com.cool.store.vo.PartnerInterviewInfoVO; import com.cool.store.vo.PartnerPassLetterDetailVO; import com.cool.store.vo.PartnerUserInfoVO; -import com.cool.store.vo.interview.CalendarInfo; -import com.cool.store.vo.interview.FreeBusyInfo; +import com.cool.store.vo.interview.CreateAppointmentVO; import com.cool.store.vo.interview.GetFreeBusyListVO; import com.cool.store.vo.interview.InterviewVO; import lombok.extern.slf4j.Slf4j; @@ -41,10 +45,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; +import java.text.MessageFormat; +import java.util.*; @Service @Slf4j @@ -62,15 +67,33 @@ public class PartnerInterviewServiceImpl implements PartnerInterviewService { @Autowired private InterviewService interviewService; + @Autowired + private HyPartnerInterviewMapper hyPartnerInterviewMapper; + + @Autowired + private HyPartnerInterviewPlanMapper hyPartnerInterviewPlanMapper; + + @Autowired + private HyPartnerLineInfoMapper hyPartnerLineInfoMapper; + + @Autowired + private EventCenterHttpRequest eventCenterHttpRequest; + + @Autowired + private LogService logService; + + @Autowired + private EnterpriseUserDAO enterpriseUserDAO; + + @Autowired + private RedisUtilPool redisUtilPool; + @Value("${trtc.sdkAppId}") private Long sdkAppId; @Value("${trtc.secretKey}") private String key; - @Autowired - private LogService logService; - /** * 加盟商查询面试信息 * @@ -222,4 +245,108 @@ public class PartnerInterviewServiceImpl implements PartnerInterviewService { return interviewService.getFreeBusyList(request); } + @Override + @Transactional + public CreateAppointmentVO createAppointment(CreateAppointmentReq request) throws ApiException { + if(request.getPartnerLineId() == null || request.getPartnerLineId()<=0){ + throw new ApiException(ErrorCodeEnum.INTERVIEW_LINE_ID_IS_NULL); + } + //如果开始时间小于当前时间需要报错 +// if(DateUtil.date().isAfter(DateUtil.parse(request.getStartBookingTime()))){ +// throw new ApiException(ErrorCodeEnum.CREATE_APPOINTMENT_TIME_ERROR); +// } + HyPartnerInterviewPlanDO hyPartnerInterviewPlanDO = new HyPartnerInterviewPlanDO(); + hyPartnerInterviewPlanDO.setPartnerLineId(request.getPartnerLineId()); + hyPartnerInterviewPlanDO.setDeleted(false); + List hyPartnerInterviewPlanDOS = hyPartnerInterviewPlanMapper.selectBySelective(hyPartnerInterviewPlanDO); + if(CollectionUtils.isNotEmpty(hyPartnerInterviewPlanDOS)&&hyPartnerInterviewPlanDOS.get(0).getId()!=null){ + throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_ALREADY_EXIST); + } + String interviewrId = request.getInterviewerId(); + if(StringUtils.isEmpty(interviewrId)){ + interviewrId = interviewService.getInterviewerByPartner(request.getPartnerId(),String.valueOf(request.getPartnerLineId())); + } + CreateAppointmentVO vo = new CreateAppointmentVO(); + String lockName = MessageFormat.format(RedisConstant.PARTNER_APPOINTMENT_LOCK, request.getPartnerLineId()); + if (Boolean.FALSE.equals(redisUtilPool.lock(lockName, request.getPartnerLineId().toString(), 10))) { + throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_ALREADY_EXIST); + } + //注册事务回调方法 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { + redisUtilPool.unlock(lockName, request.getPartnerLineId().toString()); + } + }); + + //1.创建面试计划 + HyPartnerInterviewPlanDO record = new HyPartnerInterviewPlanDO(); + String startBookingTime = request.getStartBookingTime(); + String startDate = startBookingTime.substring(0, 10); + record.setInterviewDate(Convert.toDate(startDate)); + record.setCreateTime(new Date()); + record.setUpdateTime(new Date()); + record.setStartTime(Convert.toDate(request.getStartBookingTime())); + record.setEndTime(Convert.toDate(request.getEndBookingTime())); + record.setPartnerId(request.getPartnerId()); + record.setPartnerLineId(request.getPartnerLineId()); + record.setInterviewer(interviewrId); + record.setIsPartnerInterview(0); + //生成房间号 + record.setRoomId(StringUtil.generateRoomId(startBookingTime)); + record.setRoomStatus(RoomStatus.WAIT_FOR_OPEN.getCode()); + record.setDeleted(false); + record.setApplicationApproved(0); + hyPartnerInterviewPlanMapper.insertSelective(record); + + List interviewPlanDOS = hyPartnerInterviewPlanMapper.selectBySelective(hyPartnerInterviewPlanDO); + if(CollectionUtils.isEmpty(interviewPlanDOS)){ + throw new ApiException(ErrorCodeEnum.INTERVIEW_PLAN_NOT_EXIST); + } + Long interviewPlanId = interviewPlanDOS.get(0).getId(); + vo.setInterviewPlanId(String.valueOf(interviewPlanId)); + + //2.创建面试信息 + HyPartnerInterviewDO hyPartnerInterviewDO = new HyPartnerInterviewDO(); + hyPartnerInterviewDO.setInterviewPlanId(interviewPlanId); + hyPartnerInterviewDO.setPartnerLineId(request.getPartnerLineId()); + hyPartnerInterviewDO.setPartnerId(request.getPartnerId()); + hyPartnerInterviewDO.setInterviewer(interviewrId); + hyPartnerInterviewDO.setCreateTime(new Date()); + hyPartnerInterviewDO.setUpdateTime(new Date()); + hyPartnerInterviewDO.setStatus(Integer.valueOf(WorkflowStatusEnum.RESERVATION_1.getCode())); + hyPartnerInterviewDO.setDeleted(false); + hyPartnerInterviewMapper.insertSelective(hyPartnerInterviewDO); + + //修改线索状态 + HyPartnerLineInfoDO hyPartnerLineDO = new HyPartnerLineInfoDO(); + hyPartnerLineDO.setId(request.getPartnerLineId()); + hyPartnerLineDO.setWorkflowStatus(WorkflowStatusEnum.RESERVATION_1.getCode()); + hyPartnerLineDO.setUpdateTime(new Date()); + hyPartnerLineInfoMapper.updateByPrimaryKeySelective(hyPartnerLineDO); + + //异步发送飞书信息给面试官 + InterviewVO interviewVO = hyPartnerInterviewPlanMapper.getInterviewInfo(String.valueOf(interviewPlanId)); + List userIds = new ArrayList<>(); + userIds.add(interviewrId); + Map feishuUserIdsByUserIds = enterpriseUserDAO.getFeishuUserIdsByUserIds(userIds); +// SendCardMessageDTO sendCardMessageDTO = new SendCardMessageDTO(); +// sendCardMessageDTO.setUserIds(userIds); +// sendCardMessageDTO.setMessageType(FeiShuNoticeMsgEnum.INTERVIEW_APPOINTMENT); +// sendCardMessageDTO.setMessageUrl(linkUrl); +// sendCardMessageDTO.setTitle("面试预约申请"); +// sendCardMessageDTO.setContent(generateFeiShuInterviewMsg(interviewVO.getPartnerName(), interviewVO.getPartnerMobile(), interviewVO.getStartTime())); + //替换为通过事件中心发送消息 + eventCenterHttpRequest.sendFeiShuNotice(FeiShuNoticeMsgEnum.INTERVIEW_APPOINTMENT, + Arrays.asList(feishuUserIdsByUserIds.get(interviewrId)), + interviewVO.getPartnerName(), interviewVO.getPartnerMobile(), interviewVO.getStartTime()); + + //记录日志 + PartnerUserInfoVO operator = PartnerUserHolder.getUser(); + LogBasicDTO log = LogBasicDTO.builder().mobile(operator.getMobile()).operateUserId(operator.getPartnerId()).operateUsername(operator.getUsername()).operateTime(DateUtil.format(new Date(), CoolDateUtils.DATE_FORMAT_SEC)).mobile(operator.getMobile()).build(); + logService.recordPartnerBizLog(operator,interviewVO.getPartnerLineId(),OperateTypeEnum.INTERVIEW_APPOINTMENT,log); + + return vo; + } + } diff --git a/coolstore-partner-webc/src/main/java/com/cool/store/controller/InterviewController.java b/coolstore-partner-webc/src/main/java/com/cool/store/controller/InterviewController.java index 1a9d45055..99fb6cf53 100644 --- a/coolstore-partner-webc/src/main/java/com/cool/store/controller/InterviewController.java +++ b/coolstore-partner-webc/src/main/java/com/cool/store/controller/InterviewController.java @@ -3,7 +3,6 @@ package com.cool.store.controller; import com.cool.store.dto.partner.EnterInterviewDto; import com.cool.store.dto.partner.LineQueryInterviewDto; import com.cool.store.dto.partner.PartnerGetPassLetterDetailDto; -import com.cool.store.dto.partner.PartnerQueryInterviewDto; import com.cool.store.exception.ApiException; import com.cool.store.request.CreateAppointmentReq; import com.cool.store.request.GetFreeBusyListReq; @@ -68,7 +67,7 @@ public class InterviewController { @PostMapping("/appointment/submit") @ApiOperation("预约面试") public ResponseResult createAppointment(@RequestBody CreateAppointmentReq request) throws ApiException { - return ResponseResult.success(interviewBaseService.createAppointment(request)); + return ResponseResult.success(interviewService.createAppointment(request)); } @PostMapping("/modifyInterviewTime")