|
|
|
@ -4,6 +4,7 @@ import cn.zeroerr.common.annotation.Anonymous;
|
|
|
|
|
import cn.zeroerr.common.core.controller.BaseController;
|
|
|
|
|
import cn.zeroerr.common.core.domain.AjaxResult;
|
|
|
|
|
import cn.zeroerr.common.core.domain.entity.RecruitStructure;
|
|
|
|
|
import cn.zeroerr.domain.dto.AnnouncementDTO;
|
|
|
|
|
import cn.zeroerr.domain.dto.FollowDTO;
|
|
|
|
|
import cn.zeroerr.domain.dto.HomePageDTO;
|
|
|
|
|
import cn.zeroerr.domain.dto.PostDetailDTO;
|
|
|
|
@ -30,6 +31,7 @@ import java.time.LocalDate;
|
|
|
|
|
import java.time.YearMonth;
|
|
|
|
|
import java.time.temporal.TemporalAdjusters;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.function.BiConsumer;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
@RestController
|
|
|
|
@ -75,7 +77,7 @@ public class HomePageController extends BaseController {
|
|
|
|
|
|
|
|
|
|
//寻找该月份实际入职人数(以入职管理里的为准)
|
|
|
|
|
//List<ResumeFollowRecord> resumeFollowRecordActualEntryList = resumeFollowRecordService.getBySelectMonth(req.getHrName(), firstDay, lastDay, 2);
|
|
|
|
|
List<EntryManage> entryManageList=entryManageService.getList(firstDay, lastDay);
|
|
|
|
|
List<EntryManage> entryManageList = entryManageService.getList(firstDay, lastDay);
|
|
|
|
|
|
|
|
|
|
//寻找该月份初试通过人数
|
|
|
|
|
List<ResumeFollowRecord> resumeFollowRecordFirstPassList = resumeFollowRecordService.getBySelectMonth(req.getHrName(), firstDay, lastDay, 3);
|
|
|
|
@ -86,30 +88,31 @@ public class HomePageController extends BaseController {
|
|
|
|
|
//寻找该月份接受的offer数
|
|
|
|
|
List<ResumeFollowRecord> resumeFollowRecordOfferList = resumeFollowRecordService.getBySelectMonth(req.getHrName(), firstDay, lastDay, 6);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ResumeStatVO resumeStatVO = new ResumeStatVO();
|
|
|
|
|
//1.合格简历数量
|
|
|
|
|
resumeStatVO.setQualifiedCount(resumeFollowRecordList.size());
|
|
|
|
|
//2 .初试通过人数
|
|
|
|
|
resumeStatVO.setFistCount(resumeFollowRecordFirstPassList.stream().filter(record -> Objects.nonNull(record.getFirstPass()) && "1".equals(record.getFirstPass())).count());
|
|
|
|
|
resumeStatVO.setFistCount(resumeFollowRecordFirstPassList.stream().filter(record -> "1".equals(record.getFirstPass())).count());
|
|
|
|
|
//3.通过人数(终面)
|
|
|
|
|
resumeStatVO.setFinalPassCount(resumeFollowRecordFinalPassList.stream().filter(record -> Objects.nonNull(record.getFinalPass()) && "1".equals(record.getFinalPass())).count());
|
|
|
|
|
resumeStatVO.setFinalPassCount(resumeFollowRecordFinalPassList.stream().filter(record -> "1".equals(record.getFinalPass())).count());
|
|
|
|
|
//4.未通过人数(终面)
|
|
|
|
|
resumeStatVO.setFinalFailCount(resumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getFinalPass()) && "0".equals(record.getFinalPass())).count());
|
|
|
|
|
resumeStatVO.setFinalFailCount(resumeFollowRecordList.stream().filter(record -> "0".equals(record.getFinalPass())).count());
|
|
|
|
|
//5.入职人数("实际"入职日期不为空的数据统计)
|
|
|
|
|
resumeStatVO.setEntryCount(entryManageList.size());
|
|
|
|
|
//6.简历来源:下载
|
|
|
|
|
resumeStatVO.setDownLoadCounts(resumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getResumeSource()) && "2".equals(record.getResumeSource())).count());
|
|
|
|
|
resumeStatVO.setDownLoadCounts(resumeFollowRecordList.stream().filter(record -> "2".equals(record.getResumeSource())).count());
|
|
|
|
|
//7.简历处理-自投
|
|
|
|
|
if(resumeHandleRecordList!=null){
|
|
|
|
|
if (resumeHandleRecordList != null) {
|
|
|
|
|
resumeStatVO.setSelfCounts(resumeHandleRecordList.stream()
|
|
|
|
|
.filter(record -> record.getSelfCounts() != null)
|
|
|
|
|
.mapToInt(ResumeHandleRecord::getSelfCounts)
|
|
|
|
|
.sum());
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
resumeStatVO.setSelfCounts(0);
|
|
|
|
|
}
|
|
|
|
|
//8.封装实际到面人数
|
|
|
|
|
resumeStatVO.setActualArriveCounts(resumeFollowRecordActualArrivedList.stream().filter(record -> Objects.nonNull(record.getFirstReach()) && "1".equals(record.getFirstReach())).count());
|
|
|
|
|
resumeStatVO.setActualArriveCounts(resumeFollowRecordActualArrivedList.stream().filter(record -> "1".equals(record.getFirstReach())).count());
|
|
|
|
|
//9.通过比例(终面)=通过人数(终面)/初面实际到面人数
|
|
|
|
|
//long totalCount = resumeStatVO.getFinalPassCount() + resumeStatVO.getFinalFailCount();
|
|
|
|
|
if (resumeStatVO.getActualArriveCounts() != null) {
|
|
|
|
@ -352,30 +355,34 @@ public class HomePageController extends BaseController {
|
|
|
|
|
//找到所有时间一共有多少份录入的简历
|
|
|
|
|
List<ResumeFollowRecord> allResumeFollowRecordList = resumeFollowRecordService.list();
|
|
|
|
|
//找到所有时间一共有多少人实际入职
|
|
|
|
|
List<EntryManage> allEntryManageList=entryManageService.getList(null, null);
|
|
|
|
|
List<EntryManage> allEntryManageList = entryManageService.getList(null, null);
|
|
|
|
|
|
|
|
|
|
//封装合格简历
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("合格简历:" + allResumeFollowRecordList.size() + "人").setValue((long) allResumeFollowRecordList.size()));
|
|
|
|
|
//封装电话面试通过百分比
|
|
|
|
|
//通过电话面试的人数
|
|
|
|
|
//通过
|
|
|
|
|
long phonePassCount1 = allResumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getIsPass()) && "1".equals(record.getIsPass())).count();
|
|
|
|
|
long phonePassCount1 = allResumeFollowRecordList.stream().filter(record -> "1".equals(record.getIsPass())).count();
|
|
|
|
|
//直接邀约
|
|
|
|
|
long phonePassCount2 = allResumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getIsPass()) && "4".equals(record.getIsPass())).count();
|
|
|
|
|
long phonePassCount2 = allResumeFollowRecordList.stream().filter(record -> "4".equals(record.getIsPass())).count();
|
|
|
|
|
long phonePassCount = phonePassCount1 + phonePassCount2;
|
|
|
|
|
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("电面通过:" + phonePassCount + "人").setValue(phonePassCount));
|
|
|
|
|
|
|
|
|
|
//封装到面人数
|
|
|
|
|
long arrivedCount = allResumeFollowRecordList.stream().filter(record -> "1".equals(record.getFirstReach())).count();
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("到面人数:" + arrivedCount + "人").setValue(arrivedCount));
|
|
|
|
|
|
|
|
|
|
//封装初试通过百分比
|
|
|
|
|
long firstReachCount = allResumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getFirstPass()) && "1".equals(record.getFirstPass())).count();
|
|
|
|
|
long firstReachCount = allResumeFollowRecordList.stream().filter(record -> "1".equals(record.getFirstPass())).count();
|
|
|
|
|
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("初试通过:" + firstReachCount + "人").setValue(firstReachCount));
|
|
|
|
|
|
|
|
|
|
long finalPassCount = allResumeFollowRecordList.stream().filter(record -> Objects.nonNull(record.getFinalPass()) && "1".equals(record.getFinalPass())).count();
|
|
|
|
|
long finalPassCount = allResumeFollowRecordList.stream().filter(record -> "1".equals(record.getFinalPass())).count();
|
|
|
|
|
//封装终试通过人数
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("终试通过:" + finalPassCount + "人").setValue(finalPassCount));
|
|
|
|
|
|
|
|
|
|
//封装入职人数
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("入职通过:" + allEntryManageList.size() + "人").setValue((long)allEntryManageList.size()));
|
|
|
|
|
funnelDataList.add(new ResumeStatVO.FunnelData().setName("入职通过:" + allEntryManageList.size() + "人").setValue((long) allEntryManageList.size()));
|
|
|
|
|
resumeStatVO.setFunnelData(funnelDataList);
|
|
|
|
|
|
|
|
|
|
//查询待我审批的条数
|
|
|
|
@ -438,21 +445,21 @@ public class HomePageController extends BaseController {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//封装简历合格率
|
|
|
|
|
Integer total=resumeStatVO.getFindResumeCounts()+resumeStatVO.getSelfCounts();
|
|
|
|
|
if(resumeStatVO.getQualifiedCount()!=null && total!=0){
|
|
|
|
|
Integer total = resumeStatVO.getFindResumeCounts() + resumeStatVO.getSelfCounts();
|
|
|
|
|
if (resumeStatVO.getQualifiedCount() != null && total != 0) {
|
|
|
|
|
BigDecimal arrivePercent = new BigDecimal(resumeStatVO.getQualifiedCount()).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
|
|
|
|
|
resumeStatVO.setQualifiedPercent(arrivePercent.doubleValue());
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
resumeStatVO.setQualifiedPercent(0d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//封装约面率
|
|
|
|
|
if (resumeStatVO.getInvestInterviewCounts()!=null &&resumeStatVO.getQualifiedCount()!=null){
|
|
|
|
|
if(resumeStatVO.getQualifiedCount()!=0){
|
|
|
|
|
if (resumeStatVO.getInvestInterviewCounts() != null && resumeStatVO.getQualifiedCount() != null) {
|
|
|
|
|
if (resumeStatVO.getQualifiedCount() != 0) {
|
|
|
|
|
BigDecimal arrivePercent = new BigDecimal(resumeStatVO.getInvestInterviewCounts()).divide(new BigDecimal(resumeStatVO.getQualifiedCount()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
|
|
|
|
|
resumeStatVO.setInvitePercent(arrivePercent.doubleValue());
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
resumeStatVO.setInvitePercent(0d);
|
|
|
|
|
}
|
|
|
|
|
return success(resumeStatVO);
|
|
|
|
@ -488,4 +495,74 @@ public class HomePageController extends BaseController {
|
|
|
|
|
return AjaxResult.success(postListVOList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Anonymous
|
|
|
|
|
@GetMapping("/getAnnouncement")
|
|
|
|
|
@ApiOperation(value = "获取公告数据")
|
|
|
|
|
public AjaxResult getAnnouncement() {
|
|
|
|
|
//封装公告内容
|
|
|
|
|
List<AnnouncementDTO> announcementDTOList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 获取近五天的日期范围
|
|
|
|
|
LocalDate now = LocalDate.now();
|
|
|
|
|
LocalDate fiveDaysLater = now.plusDays(5);
|
|
|
|
|
|
|
|
|
|
// 获取近五天预计入职的人,并按时间分类
|
|
|
|
|
Map<LocalDate, List<EntryManage>> groupByJoinDate = entryManageService.getListByWeek(now, fiveDaysLater)
|
|
|
|
|
.stream().collect(Collectors.groupingBy(EntryManage::getJoinDate));
|
|
|
|
|
|
|
|
|
|
// 获取近五天将要面试的人,并按时间分类
|
|
|
|
|
Map<LocalDate, List<ResumeFollowRecord>> groupByFirstDate = resumeFollowRecordService.getListByWeek(now, fiveDaysLater)
|
|
|
|
|
.stream().collect(Collectors.groupingBy(ResumeFollowRecord::getFirstDate));
|
|
|
|
|
|
|
|
|
|
// 处理预计入职的公告
|
|
|
|
|
processAnnouncements(announcementDTOList, groupByJoinDate, "预计入职候选人", AnnouncementDTO::setContentEntry);
|
|
|
|
|
|
|
|
|
|
// 处理面试公告
|
|
|
|
|
processAnnouncements(announcementDTOList, groupByFirstDate, "面试候选人", AnnouncementDTO::setContentInterview);
|
|
|
|
|
|
|
|
|
|
// 按日期排序
|
|
|
|
|
announcementDTOList.sort(Comparator.comparing(AnnouncementDTO::getDate));
|
|
|
|
|
|
|
|
|
|
return AjaxResult.success(announcementDTOList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private <T> void processAnnouncements(List<AnnouncementDTO> announcementDTOList, Map<LocalDate, List<T>> groupedData, String title, BiConsumer<AnnouncementDTO, String> setContentMethod) {
|
|
|
|
|
int count = 1;
|
|
|
|
|
for (Map.Entry<LocalDate, List<T>> entry : groupedData.entrySet()) {
|
|
|
|
|
LocalDate date = entry.getKey();
|
|
|
|
|
List<T> dataList = entry.getValue();
|
|
|
|
|
|
|
|
|
|
Optional<AnnouncementDTO> existingAnnouncement = announcementDTOList.stream()
|
|
|
|
|
.filter(announcement -> date.equals(announcement.getDate()))
|
|
|
|
|
.findFirst();
|
|
|
|
|
|
|
|
|
|
StringBuilder content = new StringBuilder();
|
|
|
|
|
for (T data : dataList) {
|
|
|
|
|
if (data instanceof EntryManage) {
|
|
|
|
|
EntryManage entryManage = (EntryManage) data;
|
|
|
|
|
content.append(entryManage.getUserName()).append(" ").append(entryManage.getPostName()).append(";");
|
|
|
|
|
} else if (data instanceof ResumeFollowRecord) {
|
|
|
|
|
ResumeFollowRecord resumeFollowRecord = (ResumeFollowRecord) data;
|
|
|
|
|
content.append(resumeFollowRecord.getName()).append(" ").append(resumeFollowRecord.getPostName()).append(";");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (existingAnnouncement.isPresent()) {
|
|
|
|
|
AnnouncementDTO announcementDTO = existingAnnouncement.get();
|
|
|
|
|
setContentMethod.accept(announcementDTO, content.toString());
|
|
|
|
|
} else {
|
|
|
|
|
AnnouncementDTO announcementDTO = new AnnouncementDTO();
|
|
|
|
|
announcementDTO.setId(count++);
|
|
|
|
|
announcementDTO.setDate(date);
|
|
|
|
|
announcementDTO.setTitleEntry("预计入职候选人".equals(title) ? title : "预计入职候选人");
|
|
|
|
|
announcementDTO.setContentEntry("预计入职候选人".equals(title) ? content.toString() : "无");
|
|
|
|
|
announcementDTO.setTitleInterview("面试候选人".equals(title) ? title : "面试候选人");
|
|
|
|
|
announcementDTO.setContentInterview("面试候选人".equals(title) ? content.toString() : "无");
|
|
|
|
|
announcementDTOList.add(announcementDTO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|