面谈/面试

This commit is contained in:
zhangchenbiao
2024-03-18 10:22:15 +08:00
parent 0bc3de972f
commit e5cbf96280
20 changed files with 474 additions and 64 deletions

View File

@@ -69,6 +69,7 @@ public class CommonConstants {
public static final String PATH_SPILT = "/";
public static final String PATH_BAR = "-";
public static final String COLON = ":";
public static final String ROOT_REGION_PATH = "/1/";
/**

View File

@@ -0,0 +1,33 @@
package com.cool.store.enums;
/**
* @author zhangchenbiao
* @FileName: AppointmentStatusEnum
* @Description:预约状态
* @date 2024-03-15 16:15
*/
public enum AppointmentStatusEnum {
//状态 0:不可预约 1:已被预约 2:可预约
NOT_APPOINTMENT(0, "不可预约"),
APPOINTMENT(1, "已被预约"),
CAN_APPOINTMENT(2, "可预约"),
;
private Integer code;
private String message;
AppointmentStatusEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,97 @@
package com.cool.store.enums;
import com.cool.store.constants.CommonConstants;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author zhangchenbiao
* @FileName: InterviewTypeEnum
* @Description:
* @date 2024-03-15 16:12
*/
public enum InterviewTypeEnum {
MEET(0, "面谈", 120, 8, 19),
INTERVIEW(1, "面试", 30, 9, 18),
;
private Integer code;
private String message;
private Integer minute;
private Integer startHour;
private Integer endHour;
InterviewTypeEnum(Integer code, String message, Integer minute, Integer startHour, Integer endHour) {
this.code = code;
this.message = message;
this.minute = minute;
this.startHour = startHour;
this.endHour = endHour;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
public Integer getMinute() {
return minute;
}
public static InterviewTypeEnum match(Integer code) {
for (InterviewTypeEnum type : InterviewTypeEnum.values()) {
if (type.getCode().equals(code)) {
return type;
}
}
return null;
}
public static List<Pair<String, Boolean>> getTimeSlots(InterviewTypeEnum interviewType, LocalDate localDate) {
switch (interviewType) {
case MEET:
return getTimeSlots(localDate, InterviewTypeEnum.MEET);
case INTERVIEW:
return getTimeSlots(localDate, InterviewTypeEnum.INTERVIEW);
default:
break;
}
return null;
}
private static List<Pair<String, Boolean>> getTimeSlots(LocalDate date, InterviewTypeEnum interviewTypeEnum) {
List<Pair<String, Boolean>> result = new ArrayList<>();
LocalDateTime start = LocalDateTime.of(date, LocalTime.of(interviewTypeEnum.startHour, CommonConstants.ZERO));
LocalDateTime now = LocalDateTime.now();
while (start.getHour() < interviewTypeEnum.endHour){
String time = start.getHour() + CommonConstants.COLON + (start.getMinute() < CommonConstants.TEN ? "0"+ start.getMinute() : start.getMinute());
boolean isAvailable = start.isAfter(now);
start = start.plusMinutes(interviewTypeEnum.minute);
time = time + CommonConstants.PATH_BAR + start.getHour() + CommonConstants.COLON + (start.getMinute() < CommonConstants.TEN ? "0"+ start.getMinute() : start.getMinute());
result.add(Pair.of(time, isAvailable));
}
return result;
}
public static void main(String[] args) {
System.out.println(getTimeSlots(LocalDate.now(), InterviewTypeEnum.INTERVIEW));
}
}

View File

@@ -1,50 +0,0 @@
package com.cool.store.dao;
import cn.hutool.core.bean.BeanUtil;
import com.cool.store.dto.content.ContentAddDto;
import com.cool.store.dto.content.ContentQueryListDto;
import com.cool.store.dto.content.ContentUpdateDto;
import com.cool.store.entity.HyContentInfoDO;
import com.cool.store.mapper.HyContentInfoMapper;
import com.cool.store.vo.HyContentInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author su'zh
*/
@Repository
@Deprecated
public class ContentDAO {
@Autowired
private HyContentInfoMapper contentInfoMapper;
public String addContentInfo(ContentAddDto dto) {
HyContentInfoDO hyContentInfoDO = new HyContentInfoDO();
BeanUtil.copyProperties(dto, hyContentInfoDO);
hyContentInfoDO.setUpdateUserId(dto.getCreateUserId());
return Integer.toString(contentInfoMapper.insertSelective(hyContentInfoDO));
}
public void deleteContent(String contentId) {
contentInfoMapper.deleteSelective(contentId);
}
public void updateContent(ContentUpdateDto dto) {
HyContentInfoDO hyContentInfoDO = new HyContentInfoDO();
BeanUtil.copyProperties(dto, hyContentInfoDO);
hyContentInfoDO.setId(Long.parseLong(dto.getContentId()));
contentInfoMapper.updateByPrimaryKeySelective(hyContentInfoDO);
}
public List<HyContentInfoVO> queryContentList(ContentQueryListDto dto) {
return contentInfoMapper.queryContentList(dto);
}
public HyContentInfoDO queryContentInfo(String contentId) {
return contentInfoMapper.queryContentInfo(contentId);
}
}

View File

@@ -0,0 +1,20 @@
package com.cool.store.dao;
import com.cool.store.mapper.LineAuditInfoMapper;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
/**
* @author zhangchenbiao
* @FileName: LineAuditInfoDAO
* @Description:
* @date 2024-03-15 16:00
*/
@Repository
public class LineAuditInfoDAO {
@Resource
private LineAuditInfoMapper lineAuditInfoMapper;
}

View File

@@ -0,0 +1,39 @@
package com.cool.store.dao;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.cool.store.entity.LineCalendarsEventDO;
import com.cool.store.mapper.LineCalendarsEventMapper;
import com.cool.store.utils.StringUtil;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
/**
* @author zhangchenbiao
* @FileName: LineCalendarsEventDAO
* @Description:
* @date 2024-03-15 16:00
*/
@Repository
public class LineCalendarsEventDAO {
@Resource
private LineCalendarsEventMapper lineCalendarsEventMapper;
public List<LineCalendarsEventDO> getInterviewerLineCalendarsEvent(String interviewer, LocalDate localDate) {
if (StringUtils.isBlank(interviewer) || Objects.isNull(localDate)) {
return null;
}
return lineCalendarsEventMapper.getInterviewerLineCalendarsEvent(interviewer, localDate.toString());
}
public List<LineCalendarsEventDO> getRegionLineCalendarsEvent(Long regionId, LocalDate localDate) {
if (Objects.isNull(regionId) || Objects.isNull(localDate)) {
return null;
}
return lineCalendarsEventMapper.getRegionLineCalendarsEvent(regionId, localDate.toString());
}
}

View File

@@ -0,0 +1,20 @@
package com.cool.store.dao;
import com.cool.store.mapper.LineInterviewMapper;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
/**
* @author zhangchenbiao
* @FileName: LineInterviewDAO
* @Description:
* @date 2024-03-15 16:01
*/
@Repository
public class LineInterviewDAO {
@Resource
private LineInterviewMapper lineInterviewMapper;
}

View File

@@ -3,5 +3,5 @@ package com.cool.store.mapper;
import com.cool.store.entity.LineAuditInfoDO;
import tk.mybatis.mapper.common.Mapper;
public interface XfsgLineAuditInfoMapper extends Mapper<LineAuditInfoDO> {
public interface LineAuditInfoMapper extends Mapper<LineAuditInfoDO> {
}

View File

@@ -1,7 +1,15 @@
package com.cool.store.mapper;
import com.cool.store.entity.LineCalendarsEventDO;
import org.apache.ibatis.annotations.Param;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
public interface LineCalendarsEventMapper extends Mapper<LineCalendarsEventDO> {
List<LineCalendarsEventDO> getInterviewerLineCalendarsEvent(@Param("interviewer")String interviewer, @Param("interviewDate")String interviewDate);
List<LineCalendarsEventDO> getRegionLineCalendarsEvent(@Param("regionId")Long regionId, @Param("interviewDate")String interviewDate);
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cool.store.mapper.XfsgLineAuditInfoMapper">
<mapper namespace="com.cool.store.mapper.LineAuditInfoMapper">
<resultMap id="BaseResultMap" type="com.cool.store.entity.LineAuditInfoDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="partner_id" jdbcType="VARCHAR" property="partnerId" />

View File

@@ -8,6 +8,7 @@
<result column="partner_id" jdbcType="VARCHAR" property="partnerId" />
<result column="event_title" jdbcType="VARCHAR" property="eventTitle" />
<result column="interview_type" jdbcType="TINYINT" property="interviewType" />
<result column="interview_date" jdbcType="TIMESTAMP" property="interviewDate" />
<result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
<result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
<result column="interviewer" jdbcType="VARCHAR" property="interviewer" />
@@ -15,4 +16,12 @@
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<select id="getInterviewerLineCalendarsEvent" resultMap="BaseResultMap">
select start_time, end_time from xfsg_line_calendars_event where interview_date = #{interviewDate} and interviewer = #{interviewer}
</select>
<select id="getRegionLineCalendarsEvent" resultMap="BaseResultMap">
select start_time, end_time from xfsg_line_calendars_event where interview_date = #{interviewDate} and region_id = #{regionId} and interview_type = '1'
</select>
</mapper>

View File

@@ -39,6 +39,12 @@ public class LineCalendarsEventDO {
@Column(name = "interview_type")
private Integer interviewType;
/**
* 面试日期
*/
@Column(name = "interview_date")
private Date interviewDate;
/**
* 面试开始时间
*/

View File

@@ -0,0 +1,110 @@
package com.cool.store.vo.interview;
import cn.hutool.core.date.DateUtil;
import com.cool.store.constants.CommonConstants;
import com.cool.store.entity.LineCalendarsEventDO;
import com.cool.store.enums.AppointmentStatusEnum;
import com.cool.store.enums.InterviewTypeEnum;
import com.cool.store.utils.CoolDateUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author zhangchenbiao
* @FileName: AppointmentTimeVO
* @Description:
* @date 2024-03-15 16:07
*/
@Data
public class AppointmentTimeVO {
@ApiModelProperty("时间")
private String time;
@ApiModelProperty("状态 0:不可预约 1:已被预约 2:可预约")
private Integer status;
public static List<AppointmentTimeVO> getAppointmentTime(LocalDate localDate, List<Pair<String, Boolean>> timeSlots, List<LineCalendarsEventDO> eventList) {
List<AppointmentTimeVO> resultList = new ArrayList<>();
if(CollectionUtils.isEmpty(eventList)){
for (Pair<String, Boolean> time : ListUtils.emptyIfNull(timeSlots)) {
resultList.add(new AppointmentTimeVO(time.getLeft(), time.getRight() ? AppointmentStatusEnum.CAN_APPOINTMENT.getCode() : AppointmentStatusEnum.NOT_APPOINTMENT.getCode()));
}
return resultList;
}
List<Pair<LocalDateTime, LocalDateTime>> eventDateTime = new ArrayList<>();
for (LineCalendarsEventDO event : eventList) {
Date startTime = event.getStartTime();
Date endTime = event.getEndTime();
LocalDateTime startDateTime = LocalDateTime.parse(DateUtil.format(startTime, CoolDateUtils.DATE_FORMAT_SEC), DateTimeFormatter.ofPattern(CoolDateUtils.DATE_FORMAT_SEC));
LocalDateTime endDateTime = LocalDateTime.parse(DateUtil.format(endTime, CoolDateUtils.DATE_FORMAT_SEC), DateTimeFormatter.ofPattern(CoolDateUtils.DATE_FORMAT_SEC));
eventDateTime.add(Pair.of(startDateTime, endDateTime));
}
for (Pair<String, Boolean> time : ListUtils.emptyIfNull(timeSlots)) {
String timeStr = time.getLeft();
boolean isAvailable = time.getRight();
String[] timeArray = timeStr.split("-");
String[] startTime = timeArray[0].split(CommonConstants.COLON);
Integer startHour = Integer.parseInt(startTime[0]);
Integer startMinute = Integer.parseInt(startTime[1]);
LocalDateTime startDateTime = LocalDateTime.of(localDate, LocalTime.of(startHour, startMinute));
String[] endTime = timeArray[1].split(CommonConstants.COLON);
Integer endHour = Integer.parseInt(endTime[0]);
Integer endMinute = Integer.parseInt(endTime[1]);
LocalDateTime endDateTime = LocalDateTime.of(localDate, LocalTime.of(endHour, endMinute));
boolean isOverlapping = false;
if(isAvailable){
for (Pair<LocalDateTime, LocalDateTime> event : eventDateTime) {
isOverlapping = isOverlapping(event.getLeft(), event.getRight(), startDateTime, endDateTime);
if(isOverlapping){
break;
}
}
}
AppointmentStatusEnum appointmentStatus = isAvailable ? AppointmentStatusEnum.CAN_APPOINTMENT : AppointmentStatusEnum.NOT_APPOINTMENT;
if (isOverlapping && appointmentStatus.equals(AppointmentStatusEnum.CAN_APPOINTMENT)){
appointmentStatus = AppointmentStatusEnum.APPOINTMENT;
}
resultList.add(new AppointmentTimeVO(time.getLeft(), appointmentStatus.getCode()));
}
return resultList;
}
public AppointmentTimeVO(String time, Integer status) {
this.time = time;
this.status = status;
}
public static boolean isOverlapping(LocalDateTime start1, LocalDateTime end1, LocalDateTime start2, LocalDateTime end2) {
// 如果第二个时间段的开始时间在第一个时间段内(包括两端点)
if (start2.isAfter(start1) && start2.isBefore(end1)) {
return true;
}
// 或者第二个时间段的结束时间在第一个时间段内(包括两端点)
if (end2.isAfter(start1) && end2.isBefore(end1)) {
return true;
}
// 或者第一个时间段的开始时间在第二个时间段内
if (start1.isAfter(start2) && start1.isBefore(end2)) {
return true;
}
// 或者第一个时间段的结束时间在第二个时间段内
if (end1.isAfter(start2) && end1.isBefore(end2)) {
return true;
}
// 如果以上条件都不满足,则说明两个时间段不重叠
return false;
}
}

View File

@@ -0,0 +1,24 @@
package com.cool.store.service;
import com.cool.store.vo.interview.AppointmentTimeVO;
import java.time.LocalDate;
import java.util.List;
/**
* @author zhangchenbiao
* @FileName: LineInterviewService
* @Description:
* @date 2024-03-15 16:04
*/
public interface LineInterviewService {
/**
* 获取预约时间
* @param lineId
* @param interviewType
* @param appointmentDate
* @return
*/
List<AppointmentTimeVO> getAppointmentTime(Long lineId, Integer interviewType, LocalDate appointmentDate);
}

View File

@@ -3,7 +3,6 @@ package com.cool.store.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.RedisConstant;
import com.cool.store.dao.ContentDAO;
import com.cool.store.dto.content.ContentAddDto;
import com.cool.store.dto.content.ContentQueryListDto;
import com.cool.store.dto.content.ContentUpdateDto;
@@ -22,9 +21,6 @@ import java.util.List;
@Service
public class ContentServiceImpl implements ContentService {
@Autowired
private ContentDAO contentDAO;
@Autowired
private HyContentInfoMapper contentInfoMapper;

View File

@@ -0,0 +1,44 @@
package com.cool.store.service.impl;
import com.cool.store.dao.LineCalendarsEventDAO;
import com.cool.store.dao.LineInterviewDAO;
import com.cool.store.entity.LineCalendarsEventDO;
import com.cool.store.enums.InterviewTypeEnum;
import com.cool.store.service.LineInterviewService;
import com.cool.store.vo.interview.AppointmentTimeVO;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
/**
* @author zhangchenbiao
* @FileName: LineInterviewServiceImpl
* @Description:
* @date 2024-03-15 16:04
*/
@Service
public class LineInterviewServiceImpl implements LineInterviewService {
@Resource
private LineInterviewDAO lineInterviewDAO;
@Resource
private LineCalendarsEventDAO lineCalendarsEventDAO;
@Override
public List<AppointmentTimeVO> getAppointmentTime(Long lineId, Integer interviewType, LocalDate appointmentDate) {
InterviewTypeEnum interviewTypeEnum = InterviewTypeEnum.match(interviewType);
List<Pair<String, Boolean>> timeSlots = InterviewTypeEnum.getTimeSlots(interviewTypeEnum, appointmentDate);
List<LineCalendarsEventDO> eventList = null;
//如果是面谈 获取招商经理的时间 如果是面试 获取大区的时间
if(InterviewTypeEnum.MEET.equals(interviewTypeEnum)){
eventList = lineCalendarsEventDAO.getInterviewerLineCalendarsEvent("1", appointmentDate);
}else{
eventList = lineCalendarsEventDAO.getRegionLineCalendarsEvent(1L, appointmentDate);
}
List<AppointmentTimeVO> resultList = AppointmentTimeVO.getAppointmentTime(appointmentDate, timeSlots, eventList);
return resultList;
}
}

View File

@@ -78,7 +78,7 @@ public class SignValidateFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
MDC.put(CommonConstants.REQUEST_ID, UUIDUtils.get32UUID());
HttpServletResponse response = (HttpServletResponse) servletResponse;
/*HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request;
String uri = request.getRequestURI();
@@ -120,9 +120,9 @@ public class SignValidateFilter implements Filter {
userStr = JSONObject.toJSONString(partnerUserInfoVO);
log.info("url:{}, userStr:{}", uri, userStr);
}
}
}*/
try {
PartnerUserHolder.setUser(userStr);
//PartnerUserHolder.setUser(userStr);
filterChain.doFilter(servletRequest, servletResponse);
} finally {
PartnerUserHolder.removeUser();

View File

@@ -126,6 +126,7 @@ public class TokenValidateFilter implements Filter {
// CurrentUserHolder.removeUser();
// MDC.clear();
// }
filterChain.doFilter(servletRequest, servletResponse);
}
@Override

View File

@@ -0,0 +1,50 @@
package com.cool.store.controller.webc;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.LineInterviewService;
import com.cool.store.vo.interview.AppointmentTimeVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
/**
* @author zhangchenbiao
* @FileName: LineInterviewController
* @Description:
* @date 2024-03-15 16:04
*/
@RestController
@RequestMapping("/interview")
@Api(tags = "面试&面谈")
@Slf4j
public class LineInterviewController {
@Resource
private LineInterviewService lineInterviewService;
@ApiOperation("获取面试/面谈 预约时间")
@GetMapping("/appointment/time")
@ApiImplicitParams({
@ApiImplicitParam(name = "lineId", value = "线索id", required = true),
@ApiImplicitParam(name = "interviewType", value = "面试类型:0面谈;1面试", required = true),
@ApiImplicitParam(name = "appointmentDate", value = "预约日期 yyyy-MM-dd", required = true)
})
public ResponseResult<List<AppointmentTimeVO>> getAppointmentTime(@RequestParam("lineId")Long lineId,
@RequestParam("interviewType")Integer interviewType,
@RequestParam("appointmentDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate appointmentDate) {
return ResponseResult.success(lineInterviewService.getAppointmentTime(lineId, interviewType, appointmentDate));
}
}

View File

@@ -1,8 +1,8 @@
#mysql config
default.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_hy?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true
default.datasource.username=hsay
default.datasource.password=Z3J7xBbgouMD
default.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_36?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true
default.datasource.username=coolstore
default.datasource.password=CSCErYcXniNYm7bT
redis.host.uri=http://userInfo:Cx111111@tstore-coolcollege.redis.rds.aliyuncs.com:6379/0
redis.isv.host.uri=http://userInfo:Cx111111@tstore-coolcollege.redis.rds.aliyuncs.com:6379/2
@@ -57,7 +57,7 @@ signKey=77fea013c3a6459685b83c21a2fc3411
fixMobileOpenid=HSAY5531DA7
#xxljob配置
#xxljob配置
xxl.job.admin.addresses=http://10.7.53.224:10001/xxl-job-admin
xxl.job.admin.addresses=
xxl.job.executor.appname=${spring.application.name}
xxl.job.executor.ip=
xxl.job.executor.port=31001
@@ -67,4 +67,6 @@ xxl.job.accessToken=25365115eed84e9ba5e0040abb255a09
exhibition.channel.id=52399
recommended.channel.id=52400
recommended.channel.id=52400
wx.pay.privateKeyPath=D:\\weixin\\apiclient_key.pem