package com.huaxu.evaluation.job; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.huaxu.client.UserCenterClient; import com.huaxu.evaluation.dao.*; import com.huaxu.evaluation.entity.*; import com.huaxu.evaluation.enums.EvaluationCycleEnums; import com.huaxu.evaluation.vo.EvaluationItemValueVo; import com.huaxu.evaluation.vo.EvaluationItemVo; import com.huaxu.evaluation.vo.EvaluationResultTaskDetailsVo; import com.huaxu.exception.ServiceException; import com.huaxu.order.dao.WorkOrderManageMapper; import com.huaxu.order.dto.WorkOrderManageDto; import com.huaxu.task.entity.UserEntity; import com.huaxu.util.DatesUtil; import com.huaxu.utils.EvaluationUtil; import io.swagger.models.auth.In; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** * @ClassName EvaluationResultJob * @Description: TODO * @Author lihui * @Date 2021/5/7 * @Version V1.0 **/ @Component @Slf4j @EnableScheduling public class EvaluationResultJob { @Autowired private WorkOrderManageMapper workOrderManageMapper; @Autowired private UserCenterClient userCenterClient; @Autowired private EvaluationCycleMapper evaluationCycleMapper; @Autowired private EvaluationResultDetailsMapper evaluationResultDetailsMapper; @Autowired private EvaluationResultMapper evaluationResultMapper; @Autowired private EvaluationResultTaskMapper evaluationResultTaskMapper; @Autowired private EvaluationItemMapper evaluationItemMapper; private static boolean lock = false; // 保存考评项目设置 static Map> itemMap = new HashMap<>(); static Map> userIdsMap = new HashMap<>(); @Scheduled(cron = "0/5 * * * * ?") @Async public void run(){ if (lock){ return; } lock = true; log.info("============绩效考评数据生成begin====================="); // 首先查询哪些公司设置了绩效考评 List evaluationCycleEntities = evaluationCycleMapper.findList(new EvaluationCycleEntity()); try { for (EvaluationCycleEntity evaluationCycleEntity : evaluationCycleEntities) { // 查询公司设置的考评日期是否是今天 if (!EvaluationUtil.isToday(evaluationCycleEntity.getEvaluationDay())) { continue; } // 如果是年度,需要检查当前日期是否是在1月份 if (evaluationCycleEntity.getType() == EvaluationCycleEnums.YEAR.getType() && !EvaluationUtil.sameMonth(1)) { continue; } userTask(evaluationCycleEntity.getTenantId(), evaluationCycleEntity.getCompanyOrgId(), evaluationCycleEntity.getType()); } } catch (Exception e) { log.error("绩效考评定时任务出错->", e); } finally { // 用完直接clear itemMap.clear(); //lock = false; } log.info("============绩效考评数据生成end====================="); } /** * @Author lihui * @Description 用户任务分解 * @Date 18:19 2021/5/10 * @Param [tenantId:租户ID, companyOrgId : 公司ID, cycle : 类型(0月度 1季度 2年度)] * @return void **/ public void userTask(String tenantId, Integer companyOrgId, Integer cycle){ // 查询该租户公司下的所有用户 String startTime = null; String endTime = null; List itemEntityList = null; List userIds = getUserIds(tenantId, companyOrgId); Map userEntityMap = toMap(userIds); if (userEntityMap == null) { return; } for (Integer userId : userIds) { UserEntity userEntity = userEntityMap.get(Long.parseLong(userId.toString())); if (userEntity == null) { continue; } itemEntityList = findItem(userEntity); // 1.获取部门考评项设置,如果未设置直接过滤 // 2.判断部门考评项目设置里面有没有设置对应的考评周期,没有就直接过滤 if (CollectionUtil.isEmpty(itemEntityList) || !EvaluationUtil.containsType(itemEntityList, cycle)) { continue; } try { // 根据类型(0月度 1季度 2年度)得到当前的开始时间和结束时间,如果是按季度,当月必须是1,4,7,10 startTime = EvaluationUtil.getStartTime(cycle, null, null); endTime = EvaluationUtil.getEndTime(cycle, null,null); if (startTime == null || endTime == null) { continue; } // 保存用户考评结果 saveEvaluationResultInfo(userEntity, itemEntityList , startTime, endTime ,cycle); } catch (Exception e) { log.error("保存用户考评信息出错->", e); } } } private List getUserIds(String tenantId, Integer companyOrgId){ String key = tenantId + "_" + companyOrgId; List result = userIdsMap.get(key); if (result == null){ result = userCenterClient.findUserIdsByPermissonOrg(tenantId, companyOrgId, null); userIdsMap.put(key, result); } return result; } /** * @Author lihui * @Description 保存用户考评结果 * @Date 10:26 2021/5/11 * @Param [userEntity, itemEntityList, startTime, endTime, cycle] * @return void **/ @Transactional public void saveEvaluationResultInfo(UserEntity userEntity, List itemEntityList, String startTime, String endTime, Integer cycle){ Calendar calendar = EvaluationUtil.getCalendar(endTime); // 计算用户完成任务情况 EvaluationResultTaskEntity taskDetailsVo = calculationTaskInfo(userEntity.getId().intValue(), userEntity.getTenantId(), startTime, endTime, getValueCondition(itemEntityList)); // 组装考评结果数据 EvaluationResultEntity resultEntity = packagesEvaluationResultEntity(userEntity, calendar, cycle, startTime, endTime); // 保存考评结果 if (evaluationResultMapper.insertEvaluationResult(resultEntity) != 1) { throw new ServiceException(500, "保存考评结果出错,退出。"); } Integer resultId = resultEntity.getId().intValue(); taskDetailsVo.setEvaluationResultId(resultId); // 保存考评结果任务详情 evaluationResultTaskMapper.insertEvaluationResultTask(taskDetailsVo); BigDecimal completeCount = new BigDecimal(taskDetailsVo.getCompleteCount()) ; BigDecimal completionRate = taskDetailsVo.getCompletionRate(); BigDecimal evaluationValue = null; for (EvaluationItemVo item : itemEntityList) { // 不是当前季度的,过滤 if (item.getCycle().indexOf(cycle.toString()) == -1 || item.getType() == null) { continue; } evaluationValue = item.getType() == 1 ? completeCount : completionRate; EvaluationResultDetailsEntity detailsEntity = new EvaluationResultDetailsEntity(); detailsEntity.setEvaluationResultId(resultId); detailsEntity.setEvaluationItemId(item.getItemId()); detailsEntity.setValue(getScore(item.getType(), item.getEvaluationItemValueVoList(), evaluationValue)); detailsEntity.setDateCreate(new Date()); detailsEntity.setDateUpdate(new Date()); detailsEntity.setTenantId(userEntity.getTenantId()); detailsEntity.setStatus(1); evaluationResultDetailsMapper.insertEvaluationResultDetails(detailsEntity); } } /** * @Author lihui * @Description 计算用户完成任务情况 * @Date 17:38 2021/5/10 * @Param [userId, tenantId, startTime, endTime,valueCondition:延期时间多少分钟内算正常] * @return void **/ private EvaluationResultTaskEntity calculationTaskInfo(Integer userId, String tenantId, String startTime, String endTime, BigDecimal valueCondition) { int page = 1; IPage iPage = null; EvaluationResultTaskEntity taskEntity = new EvaluationResultTaskEntity(); boolean completedBoolean = false; while (true) { iPage = new Page<>(page, 200); // 查询该用户的工单和任务 Page pageList = workOrderManageMapper.selectByTime(iPage, userId, tenantId, startTime, endTime); if (pageList == null || CollectionUtil.isEmpty(pageList.getRecords())) { break; } for (WorkOrderManageDto dto : pageList.getRecords()) { completedBoolean = EvaluationUtil.completed(dto.getOrderStatus()); taskEntity.setTotalCount(taskEntity.getTotalCount() + 1); taskEntity.setCompleteCount(taskEntity.getCompleteCount() + (completedBoolean ? 1 : 0)); taskEntity.setNoCompleteCount(taskEntity.getNoCompleteCount() + (!completedBoolean ? 1 : 0)); int addMinute = valueCondition == null ? EvaluationUtil.minute(dto.getDateLimit()) : valueCondition.intValue(); // 计算完成的是否属于延期完成 if (completedBoolean && EvaluationUtil.isDelay(dto.getFinishDate(), dto.getPlanFinishDate(), addMinute)) { taskEntity.setDelayCompleteCount(taskEntity.getDelayCompleteCount() + 1); } } page ++; } // 计算完成率和延期率 taskEntity.setCompletionRate(EvaluationUtil.divide(taskEntity.getCompleteCount(),taskEntity.getTotalCount())); taskEntity.setDelayRate(EvaluationUtil.divide(taskEntity.getDelayCompleteCount(),taskEntity.getTotalCount())); taskEntity.setTenantId(tenantId); taskEntity.setStatus(1); taskEntity.setDateCreate(new Date()); return taskEntity; } /** * @Author lihui * @Description 获取部门考评项 * @Date 17:36 2021/5/10 * @Param [userEntity] * @return java.util.List **/ private List findItem(UserEntity userEntity){ Integer companyOrgId = EvaluationUtil.toInteger(userEntity.getCompanyOrgId()); Integer deptOrgId = EvaluationUtil.toInteger(userEntity.getDeptOrgId()); String tenantId = userEntity.getTenantId(); String key = tenantId + "_" + companyOrgId + "_" + deptOrgId; List itemVos = itemMap.get(key); if (itemVos != null) { return itemVos; } EvaluationItemEntity queryItem = new EvaluationItemEntity(); queryItem.setCompanyOrgId(companyOrgId); queryItem.setDeptOrgId(deptOrgId); queryItem.setTenantId(tenantId); itemVos = evaluationItemMapper.findListItem(queryItem); itemMap.put(key, itemVos); return itemVos; } /** * @Author lihui * @Description 组装考评结果数据 * @Date 15:03 2021/5/11 * @Param [userEntity, calendar, cycle, startTime, endTime] * @return com.huaxu.evaluation.entity.EvaluationResultEntity **/ private EvaluationResultEntity packagesEvaluationResultEntity(UserEntity userEntity, Calendar calendar, Integer cycle, String startTime, String endTime){ EvaluationResultEntity resultEntity = new EvaluationResultEntity(); resultEntity.setYear(calendar.get(Calendar.YEAR)); resultEntity.setMonth(calendar.get(Calendar.MONTH) + 1); resultEntity.setEvaluationBe(userEntity.getUsername()); resultEntity.setEvaluationBeUserId(userEntity.getId()); resultEntity.setCycle(cycle); resultEntity.setState(0); resultEntity.setDateStart(DatesUtil.parseDate(startTime, "yyyy-MM-dd HH:mm:ss")); resultEntity.setDateEnd(DatesUtil.parseDate(endTime, "yyyy-MM-dd HH:mm:ss")); resultEntity.setTenantId(userEntity.getTenantId()); resultEntity.setCompanyOrgId(EvaluationUtil.toInteger(userEntity.getCompanyOrgId())); resultEntity.setDeptOrgId(EvaluationUtil.toInteger(userEntity.getDeptOrgId())); resultEntity.setDateCreate(new Date()); resultEntity.setStatus(1); return resultEntity; } private Map toMap(List userIds){ List userEntities = userCenterClient.findUserIdsByUserIds(EvaluationUtil.toLong(userIds)); if (CollectionUtil.isEmpty(userEntities)){ return null; } return userEntities.stream().collect(Collectors.toMap(UserEntity::getId, a -> a,(k1, k2)->k1)); } /** * @Author lihui * @Description 获取对应的分数 * @Date 11:25 2021/5/14 * @Param [type, list, evaluationValue] * @return java.math.BigDecimal **/ private BigDecimal getScore (Integer type, List list, BigDecimal evaluationValue){ if (type != 1 && type != 2) { return null; } Integer itemType = null; BigDecimal itemValue = null; BigDecimal valueOne = null; BigDecimal valueTwo = null; for (EvaluationItemValueVo evaluationItemValueVo: list) { itemType = evaluationItemValueVo.getItemType(); itemValue = evaluationItemValueVo.getItemValue(); valueOne = evaluationItemValueVo.getValueOne(); valueTwo = evaluationItemValueVo.getValueTwo(); // 大于等于 0大于等于 2小于 1介于 if (itemType == 0 && evaluationValue.compareTo(valueOne) > -1) { return itemValue; } // 小于 if (itemType == 2 && evaluationValue.compareTo(valueOne) == -1) { return itemValue; } // 介于 : 比如取8-10,就是≥8,<10 if (itemType == 1 && evaluationValue.compareTo(valueOne) > -1 && evaluationValue.compareTo(valueTwo) == -1) { return itemValue; } } return new BigDecimal("0"); } /** * @Author lihui * @Description 获取任务按时完成率设定的条件值 * @Date 9:40 2021/5/11 * @Param [itemEntityList] * @return java.math.BigDecimal **/ private BigDecimal getValueCondition(List itemEntityList){ for (EvaluationItemVo evaluationItemVo: itemEntityList) { if (evaluationItemVo.getType() == 2) { return evaluationItemVo.getValueCondition(); } } return null; } }