|
@@ -1,5 +1,35 @@
|
|
|
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
|
|
@@ -7,5 +37,311 @@ package com.huaxu.evaluation.job;
|
|
|
* @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<String, List<EvaluationItemVo>> itemMap = new HashMap<>();
|
|
|
+
|
|
|
+ static Map<String, List<Integer>> userIdsMap = new HashMap<>();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //@Scheduled(cron = "0/5 * * * * ?")
|
|
|
+ @Async
|
|
|
+ public void run(){
|
|
|
+ if (lock){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ lock = true;
|
|
|
+ log.info("============绩效考评数据生成begin=====================");
|
|
|
+ // 首先查询哪些公司设置了绩效考评
|
|
|
+ List<EvaluationCycleEntity> 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){
|
|
|
+ // 查询该租户公司下的所有用户
|
|
|
+ List<Integer> userIds = getUserIds(tenantId, companyOrgId);
|
|
|
+ Map<Long, UserEntity> userEntityMap = toMap(userIds);
|
|
|
+ String startTime = null;
|
|
|
+ String endTime = null;
|
|
|
+ List<EvaluationItemVo> itemEntityList = null;
|
|
|
+ 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<Integer> getUserIds(String tenantId, Integer companyOrgId){
|
|
|
+ String key = tenantId + "_" + companyOrgId;
|
|
|
+ List<Integer> 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<EvaluationItemVo> 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<WorkOrderManageDto> iPage = null;
|
|
|
+ EvaluationResultTaskEntity taskEntity = new EvaluationResultTaskEntity();
|
|
|
+ boolean completedBoolean = false;
|
|
|
+ while (true) {
|
|
|
+ iPage = new Page<>(page, 200);
|
|
|
+ // 查询该用户的工单和任务
|
|
|
+ Page<WorkOrderManageDto> 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<com.huaxu.evaluation.entity.EvaluationItemEntity>
|
|
|
+ **/
|
|
|
+ private List<EvaluationItemVo> 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<EvaluationItemVo> 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<Long, UserEntity> toMap(List<Integer> userIds){
|
|
|
+ List<UserEntity> 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));
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal getScore (Integer type, List<EvaluationItemValueVo> 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<EvaluationItemVo> itemEntityList){
|
|
|
+ for (EvaluationItemVo evaluationItemVo: itemEntityList) {
|
|
|
+ if (evaluationItemVo.getType() == 2) {
|
|
|
+ return evaluationItemVo.getValueCondition();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
}
|