diff --git a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-client/src/main/java/com/elink/esua/epdc/constant/KpiFieldConstant.java b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-client/src/main/java/com/elink/esua/epdc/constant/KpiFieldConstant.java index cfa67658a..b41c98797 100644 --- a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-client/src/main/java/com/elink/esua/epdc/constant/KpiFieldConstant.java +++ b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-client/src/main/java/com/elink/esua/epdc/constant/KpiFieldConstant.java @@ -15,6 +15,7 @@ public interface KpiFieldConstant { String START_DATE = "START_DATE"; String END_DATE = "END_DATE"; String DEPT_ID = "DEPT_ID"; + String KPI_CYCLE = "KPI_CYCLE"; String REFERENCE_ID = "REFERENCE_ID"; String DATA_CODE = "DATA_CODE"; diff --git a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/controller/KpiRuleController.java b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/controller/KpiRuleController.java index 280c19adb..62516384f 100644 --- a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/controller/KpiRuleController.java +++ b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/controller/KpiRuleController.java @@ -158,7 +158,8 @@ public class KpiRuleController { * @date 2019/12/17 17:04 */ @GetMapping("calcByCode/{ruleCode}") - public Result> calcByRuleCode(@PathVariable("ruleCode") String ruleCode) { - return kpiRuleService.calcByRuleCode(ruleCode); + public Result calcByRuleCode(@PathVariable("ruleCode") String ruleCode) { + kpiRuleService.calcByRuleCode(ruleCode); + return new Result(); } } diff --git a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/KpiRuleService.java b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/KpiRuleService.java index 97b82ee33..ac1671b6b 100644 --- a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/KpiRuleService.java +++ b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/KpiRuleService.java @@ -150,5 +150,5 @@ public interface KpiRuleService extends BaseService { **/ Result> listKpiRuleDTO(); - Result> calcByRuleCode(String ruleCode); + void calcByRuleCode(String ruleCode); } diff --git a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/impl/KpiMetaDataServiceImpl.java b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/impl/KpiMetaDataServiceImpl.java index dc683eb9f..a853a7483 100644 --- a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/impl/KpiMetaDataServiceImpl.java +++ b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/service/impl/KpiMetaDataServiceImpl.java @@ -42,6 +42,7 @@ import com.elink.esua.epdc.enums.KpiMetaDataEnum; import com.elink.esua.epdc.feign.EventFeignClient; import com.elink.esua.epdc.service.KpiMetaDataService; import com.elink.esua.epdc.utils.DeptUtils; +import com.elink.esua.epdc.utils.KpiLocalDateUtils; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -168,27 +169,14 @@ public class KpiMetaDataServiceImpl extends BaseServiceImpl implements KpiRuleService { private Logger logger = LoggerFactory.getLogger(getClass()); - //公式参数表 + /** + * 公式参数表 + */ @Autowired private KpiRuleParamDao kpiRuleParamDao; - //绩效考核公式表 + /** + * 绩效考核公式表 + */ @Autowired private KpiFormulaDao kpiFormulaDao; - //考核规则表 + /** + * 考核规则表 + */ @Autowired private KpiRuleDao kpiRuleDao; - //绩效考核元数据表 + /** + * 绩效考核元数据表 + */ @Autowired private KpiMetaDataDao kpiMetaDataDao; - //网格考核最终得分表 + /** + * 网格考核最终得分表 + */ @Autowired private KpiResultGridDao kpiResultGridDao; @Autowired private DeptUtils deptUtils; - //网格考核最终得分 + /** + * 网格考核最终得分 + */ @Autowired private KpiResultSuperiorDao kpiResultSuperiorDao; @@ -291,361 +303,289 @@ public class KpiRuleServiceImpl extends BaseServiceImpl> calcByRuleCode(String ruleCode) { - if ("month_grid_work_score".equals(ruleCode)){ //计算 月度网格考核之平时工作成效 - return this.calcWorkScoreByRuleCode(ruleCode); - }else if ("calcBaseGridFinalScore".equals(ruleCode)){ //计算 计算基础网格月度、季度、年度总得分 - return this.calcBaseGridFinalScoreByRuleCode(ruleCode); - }else if ("calcDistrictStreetGeneralRule".equals(ruleCode)){ //计算区直/街道考核最终得分(总规则) - return this.calcDistrictStreetGeneralRule(ruleCode); - } - return new Result(); - } - - /** - * @Description: 计算 月度网格考核之平时工作成效 - * @Param: [ruleCode] - * @return: com.elink.esua.epdc.commons.tools.utils.Result - * @Author: zy - * @Date: 2019-12-19 - */ - public Result calcWorkScoreByRuleCode(String ruleCode){ + public void calcByRuleCode(String ruleCode) { // 查询考核规则表 - KpiRuleDTO kpiRuleDTO = kpiRuleDao.queryKpiRuleMetaFormula(ruleCode); - //每次JOB启动时,根据当前时间,获取时间范围 - Map mapDate = this.initKpiParam(kpiRuleDTO.getKpiCycle(), "calcWorkScoreByRuleCode"); - if (mapDate != null){ - // 根据 考核规则表-外键(公式id),查询绩效考核公式表,待运行公式方法 - KpiFormulaDTO kpiFormulaDTO = kpiFormulaDao.queryFormula(kpiRuleDTO.getReferenceId()); - // 根据 考核规则表-主键,查询公式参数表,排序:1,2,3,4,5 - List ruleParamList = kpiRuleParamDao.queryFormulaParam(kpiRuleDTO.getId()); - List metaDateCodeList = Lists.newArrayList(); - for (int i = 0; i < ruleParamList.size(); i++) { - metaDateCodeList.add(ruleParamList.get(i).getMetaDataCode()); - } - - int pageSize = NumConstant.THIRTY; - int pageIndex = NumConstant.ONE; - List deptIdList = deptUtils.getDeptIdList(OrganizationTypeConstant.ORG_TYPE_GRID_PARTY, pageSize, pageIndex); - do { - - for (Long deptId : deptIdList) { - - BigDecimal[] paramValue = selectArrayOfMetaDate(deptId, mapDate.get("startDate"), mapDate.get("endDate"), metaDateCodeList); - //参数准备完全时,执行js运算 - if (paramValue.length == kpiFormulaDTO.getParamAmount()) { - BigDecimal workScore; - try { - //获得一个javascipt的执行引擎 - ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); - //执行js代码:参数为:公式运行方法 - engine.eval(kpiFormulaDTO.getFormula()); - //是否可调用方法 - boolean flag = engine instanceof Invocable; - if (!flag) { - return new Result().error("运行方法异常"); - } - Invocable in = (Invocable) engine; - //执行js中的函数 参数:js方法名 + 参数 - Double result = (Double) in.invokeFunction(kpiFormulaDTO.getFunctionName(), paramValue); - Double workScoreDoouble = (double) Math.round(result * 100) / 100; - workScore = new BigDecimal(workScoreDoouble); - // 网格考核最终得分 表操作 - KpiResultGridEntity kpiManualScoreEntity = new KpiResultGridEntity(); - kpiManualScoreEntity.setWorkScore(workScore); - kpiManualScoreEntity.setGridId(deptId); - kpiManualScoreEntity.setStartDate(mapDate.get("startDate")); - kpiManualScoreEntity.setEndDate(mapDate.get("endDate")); - kpiManualScoreEntity.setKpiCycle(kpiRuleDTO.getKpiCycle()); - this.saveOrUpdateKpiResult(kpiManualScoreEntity); - } catch (Exception e) { - e.printStackTrace(); - return new Result().error("运行方法异常" + e.getMessage()); - } - } - } - pageIndex++; - deptIdList = deptUtils.getDeptIdList(OrganizationTypeConstant.ORG_TYPE_GRID_PARTY, pageSize, pageIndex); - } while (CollUtil.isNotEmpty(deptIdList)); + KpiRuleDTO kpiRule = kpiRuleDao.queryKpiRuleMetaFormula(ruleCode); + String ruleMode = kpiRule.getRuleMode(); + if (StringUtils.isBlank(ruleMode) || !ruleMode.equals(KpiRuleModeEnum.FORMULA.value())) { + logger.error("规则编码{}对应的ruleMode不合法,方法中止。", ruleCode); + return; } - return new Result(); - } - - /** - * @Description: 按规则代码计算基本网格最终分数 - * @Param: [ruleCode] - * @return: com.elink.esua.epdc.commons.tools.utils.Result - * @Author: zy - * @Date: 2019-12-19 - */ - public Result calcBaseGridFinalScoreByRuleCode(String ruleCode){ - KpiResultGridEntity kpiResultGridEntity = new KpiResultGridEntity(); - // 查询考核规则表 - KpiRuleDTO kpiRuleDTO = kpiRuleDao.queryKpiRuleMetaFormula(ruleCode); + String kpiCycle = kpiRule.getKpiCycle(); + Date startDate = KpiLocalDateUtils.getKpiCycoleStartDate(kpiCycle); + if (null == startDate) { + logger.error("当前时间:{},无法按照规则编码{}计算绩效考核得分", LocalDateTime.now().toString(), ruleCode); + return; + } + // 考核结束日 + Date endDate = LocalDateUtils.localDateToDate(YearMonth.now().minusMonths(NumConstant.ONE).atEndOfMonth()); // 根据 考核规则表-外键(公式id),查询绩效考核公式表,待运行公式方法 - KpiFormulaDTO kpiFormulaDTO = kpiFormulaDao.queryFormula(kpiRuleDTO.getReferenceId()); - - // 考核周期 - String kpiCycle = kpiRuleDTO.getKpiCycle(); - //每次JOB启动时,根据当前时间,获取时间范围 - Map mapDate = this.initKpiParam(kpiCycle, "calcBaseGridFinalScoreByRuleCode"); - if (mapDate != null) { - kpiResultGridEntity.setEndDate(mapDate.get("endDate")); - kpiResultGridEntity.setStartDate(mapDate.get("startDate")); - //查询网格最终得分:所有网格 - List resultGrid = kpiResultGridDao.selectKpiResultGrid(kpiResultGridEntity); - for (KpiResultGridEntity kpi : resultGrid){ - BigDecimal finalScore; - try { - //获得一个javascipt的执行引擎 - ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); - //执行js代码:参数为:公式运行方法 - engine.eval(kpiFormulaDTO.getFormula()); - //是否可调用方法 - boolean flag = engine instanceof Invocable; - if (!flag) { - return new Result().error("运行方法异常"); + KpiFormulaDTO kpiFormula = kpiFormulaDao.queryFormula(kpiRule.getReferenceId()); + // 初始化JavaScript引擎 + Invocable invocable = this.initInvocable(kpiFormula.getFormula(), ruleCode); + // 公式所有参数对应的元数据编码、升序排列 + List metaDateCodeList = this.getRuleParmOfMetaDateCodeList(kpiRule.getId()); + // 公式参数数量 + Integer paramAmount = kpiFormula.getParamAmount(); + // 公式方法名 + String functionName = kpiFormula.getFunctionName(); + // 部门类别 + String[] deptTypeKeyArray = kpiRule.getDeptTypeKey().split(StrConstant.COMMA); + if (deptTypeKeyArray.length > NumConstant.ZERO) { + for (String deptTypeKey : deptTypeKeyArray) { + int pageIndex = NumConstant.ONE; + List deptIdList = deptUtils.getDeptIdList(deptTypeKey, NumConstant.TWENTY, pageIndex); + do { + for (Long deptId : deptIdList) { + BigDecimal[] paramValue = selectArrayOfMetaDataValue(deptId, startDate, endDate, metaDateCodeList); + // 参数准备完全时,执行js运算 + if (paramValue.length == paramAmount) { + // 执行js中的函数 参数:js方法名 + 参数 + Double score = this.calcByJavaScript(invocable, functionName, ruleCode, paramValue); + this.packageFormulaResultToSaveOrUpdate(deptId, ruleCode, score, startDate, endDate, kpiCycle); + } } - Invocable in = (Invocable) engine; - //执行js中的函数 参数:js方法名 + 参数 - Double result = (Double) in.invokeFunction(kpiFormulaDTO.getFunctionName(), kpi.getManualScore(),kpi.getWorkScore()); - Double finalScoreDoouble = (double) Math.round(result * 100) / 100; - finalScore = new BigDecimal(finalScoreDoouble); - // 网格考核最终得分 表操作 - KpiResultGridEntity kpiManualScore = new KpiResultGridEntity(); - kpiManualScore.setFinalScore(finalScore); - kpiManualScore.setId(kpi.getId()); - kpiResultGridDao.updateById(kpiManualScore); - } catch (Exception e) { - e.printStackTrace(); - return new Result().error("运行方法异常" + e.getMessage()); - } + pageIndex++; + deptIdList = deptUtils.getDeptIdList(deptTypeKey, NumConstant.TWENTY, pageIndex); + } while (CollUtil.isNotEmpty(deptIdList)); } } - return new Result(); } - private BigDecimal[] selectArrayOfMetaDate(Long deptId, Date startDate, Date endDate, List metaDateCodeList) { - - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq(KpiFieldConstant.START_DATE, startDate) - .eq(KpiFieldConstant.END_DATE, endDate) - .eq(KpiFieldConstant.DEPT_ID, deptId) - .in(KpiFieldConstant.DATA_CODE, metaDateCodeList); - - List metaDataList = kpiMetaDataDao.selectList(wrapper); - BigDecimal[] metaDataValueArray = new BigDecimal[metaDataList.size()]; + /** + * 执行保存得分操作 + * + * @param deptId 部门id + * @param ruleCode 考核规则编码 + * @param score 得分 + * @param startDate 开始日 + * @param endDate 结束日 + * @param kpiCycle 考核周期 + * @return void + * @author work@yujt.net.cn + * @date 2019/12/25 10:56 + */ + private void packageFormulaResultToSaveOrUpdate(Long deptId, String ruleCode, Double score, Date startDate, Date endDate, String kpiCycle) { + switch (ruleCode) { + /** + * 基础网格平时工作成效 + */ + case KpiScheduleCodeConstant.GRID_WORK_SCORE_MONTH: + case KpiScheduleCodeConstant.GRID_WORK_SCORE_QUARTER: + case KpiScheduleCodeConstant.GRID_WORK_SCORE_YEAR: + this.saveOrUpdateGridKpiResult(deptId, score, startDate, endDate, kpiCycle); + break; + /** + * 基础网格考核最终得分 + */ + case KpiScheduleCodeConstant.GRID_FINAL_SCORE_MONTH: + case KpiScheduleCodeConstant.GRID_FINAL_SCORE_QUARTER: + case KpiScheduleCodeConstant.GRID_FINAL_SCORE_YEAR: + this.updateGridKpiFinalScore(deptId, score, startDate, endDate, kpiCycle); + break; + /** + * 区直/街道考核最终得分 + */ + case KpiScheduleCodeConstant.SUPERIOR_FINAL_SCORE_MONTH: + case KpiScheduleCodeConstant.SUPERIOR_FINAL_SCORE_QUARTER: + case KpiScheduleCodeConstant.SUPERIOR_FINAL_SCORE_YEAR: + this.saveSuperiorKpiResult(deptId, score, startDate, endDate, kpiCycle); + break; + default: + return; + } + } - String metaDataCode; - for (int i = 0; i < metaDateCodeList.size(); i++) { - metaDataCode = metaDateCodeList.get(i); - for (KpiMetaDataEntity kpiMetaDataEntity : metaDataList) { - if (kpiMetaDataEntity.getDataCode().equals(metaDataCode)) { - metaDataValueArray[i] = kpiMetaDataEntity.getDataValue(); - } - } + /** + * 使用JavaScriptEngine执行运算方法 + * + * @param invocable JavaScriptEngine引擎 + * @param functionName JavaScript方法名 + * @param ruleCode 考核规则编码 + * @param paramValue JavaScript方法所需所有参数 + * @return java.lang.Double + * @author work@yujt.net.cn + * @date 2019/12/25 10:28 + */ + private Double calcByJavaScript(Invocable invocable, String functionName, String ruleCode, BigDecimal[] paramValue) { + try { + return (Double) invocable.invokeFunction(functionName, paramValue); + } catch (Exception e) { + logger.error("javascipt执行失败,当前时间:{},考核规则编码:{}", LocalDateTime.now().toString(), ruleCode); + throw new RenException("绩效考核定时任务执行失败2"); } - return metaDataValueArray; } /** - * 更新或插入考核结果 + * 更新网格考核结果表平时工作成效字段,更新失败则执行插入 * - * @param kpiResultGridEntity : deptId, scoreStartDate, scoreEndDate, workScore + * @param deptId 网格id + * @param score 得分 + * @param startDate 开始日 + * @param endDate 结束日 + * @param kpiCycle 考核周期 * @return void - * @author zhangyong - * @date 2019/12/18 15:56 + * @author work@yujt.net.cn + * @date 2019/12/25 10:35 */ - private void saveOrUpdateKpiResult(KpiResultGridEntity kpiResultGridEntity) { - //运算结果存储在 网格考核最终得分表 manual_score字段,:唯一性条件(deptId,scoreStartDate,scoreEndDate) - KpiResultGridDTO kpiResultGridDto = getKpiresultGrid(kpiResultGridEntity.getGridId(), kpiResultGridEntity.getStartDate(), kpiResultGridEntity.getEndDate()); - DeptLevelAndLeaderDTO deptLevelInfo = deptUtils.getDeptLevelInfo(kpiResultGridEntity.getGridId(), YesOrNoEnum.YES); - if (kpiResultGridDto != null) { - kpiResultGridEntity.setId(kpiResultGridDto.getId()); - kpiResultGridEntity.setLeaderName(deptLevelInfo.getLeaderName()); - kpiResultGridDao.updateById(kpiResultGridEntity); - } else { - kpiResultGridEntity.setParentDeptIds(deptLevelInfo.getParentDeptIds()); - kpiResultGridEntity.setParentDeptNames(deptLevelInfo.getParentDeptNames()); - kpiResultGridEntity.setAllDeptIds(deptLevelInfo.getAllDeptIds()); - kpiResultGridEntity.setAllDeptNames(deptLevelInfo.getAllDeptNames()); - kpiResultGridEntity.setLeaderName(deptLevelInfo.getLeaderName()); - kpiResultGridDao.insert(kpiResultGridEntity); + private void saveOrUpdateGridKpiResult(Long deptId, Double score, Date startDate, Date endDate, String kpiCycle) { + KpiResultGridEntity gridKpiResultEntity = new KpiResultGridEntity(); + BigDecimal kpiScore = BigDecimal.valueOf(score).setScale(NumConstant.TWO, BigDecimal.ROUND_HALF_UP); + gridKpiResultEntity.setWorkScore(kpiScore); + int update = kpiResultGridDao.update(gridKpiResultEntity, this.updateGridKpiResultWrapper(deptId, startDate, endDate, kpiCycle)); + if (update == NumConstant.ZERO) { + gridKpiResultEntity.setGridId(deptId); + gridKpiResultEntity.setStartDate(startDate); + gridKpiResultEntity.setEndDate(endDate); + gridKpiResultEntity.setKpiCycle(kpiCycle); + kpiResultGridDao.insert(gridKpiResultEntity); } } /** - * 查询考核结果 + * 更新网格考核最终的得分字段 * - * @param deptId 部门id - * @param stateDate 开始日期 - * @param endDate 结束日期 - * @return com.elink.esua.epdc.dto.KpiResultGridDTO - * @author zy - * @date 2019/12/19 15:56 + * @param deptId 网格id + * @param score 得分 + * @param startDate 开始日 + * @param endDate 结束日 + * @param kpiCycle 考核周期 + * @return void + * @author work@yujt.net.cn + * @date 2019/12/25 10:50 */ - private KpiResultGridDTO getKpiresultGrid(Long deptId, Date stateDate, Date endDate) { - Map map = new HashMap<>(); - map.put("deptId", deptId); - map.put("scoreStartDate", stateDate); - map.put("scoreEndDate", endDate); - return kpiResultGridDao.selectManualScoringISExist(map); + private void updateGridKpiFinalScore(Long deptId, Double score, Date startDate, Date endDate, String kpiCycle) { + KpiResultGridEntity gridKpiResultEntity = new KpiResultGridEntity(); + BigDecimal kpiScore = BigDecimal.valueOf(score).setScale(NumConstant.TWO, BigDecimal.ROUND_HALF_UP); + gridKpiResultEntity.setFinalScore(kpiScore); + kpiResultGridDao.update(gridKpiResultEntity, this.updateGridKpiResultWrapper(deptId, startDate, endDate, kpiCycle)); } /** - * @Description: 计算区直/街道考核最终得分(总规则) - * @Param: [ruleCode] - * @return: com.elink.esua.epdc.commons.tools.utils.Result - * @Author: zy - * @Date: 2019-12-23 + * 组装更新网格考核结果表的wrapper + * + * @param deptId 网格id + * @param startDate 开始日 + * @param endDate 结束日 + * @param kpiCycle 考核周期 + * @return com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper + * @author work@yujt.net.cn + * @date 2019/12/25 10:49 */ - public Result calcDistrictStreetGeneralRule(String ruleCode){ + private UpdateWrapper updateGridKpiResultWrapper(Long deptId, Date startDate, Date endDate, String kpiCycle) { + UpdateWrapper wrapper = new UpdateWrapper<>(); + wrapper.eq(FieldConstant.GRID_ID, deptId) + .eq(KpiFieldConstant.START_DATE, startDate) + .eq(KpiFieldConstant.END_DATE, endDate) + .eq(KpiFieldConstant.KPI_CYCLE, kpiCycle); + return wrapper; + } + + /** + * 插入 街道/区直考核结果表 + * + * @param deptId 部门id + * @param score 得分 + * @param startDate 开始日 + * @param endDate 结束日 + * @param kpiCycle 考核周期 + * @return void + * @author work@yujt.net.cn + * @date 2019/12/25 10:54 + */ + private void saveSuperiorKpiResult(Long deptId, Double score, Date startDate, Date endDate, String kpiCycle) { + DeptLevelAndLeaderDTO deptLevelInfo = deptUtils.getDeptLevelInfo(deptId, YesOrNoEnum.YES); KpiResultSuperiorEntity kpiResultSuperiorEntity = new KpiResultSuperiorEntity(); - KpiRuleDTO kpiRuleDTO = kpiRuleDao.queryKpiRuleMetaFormula(ruleCode);// 查询考核规则表 - - // 考核周期 - String kpiCycle = kpiRuleDTO.getKpiCycle(); - //每次JOB启动时,根据当前时间,获取时间范围 - Map mapDate = this.initKpiParam(kpiCycle, "calcDistrictStreetGeneralRule"); - if (mapDate != null) { - kpiResultSuperiorEntity.setEndDate(mapDate.get("endDate")); - kpiResultSuperiorEntity.setStartDate(mapDate.get("startDate")); - kpiResultSuperiorEntity.setKpiCycle(kpiCycle); - - // 根据 考核规则表-主键,查询公式参数表,排序:1,2,3,4,5,6 - List ruleParamList = kpiRuleParamDao.queryFormulaParam(kpiRuleDTO.getId()); - List metaDateCodeList = Lists.newArrayList(); - for (int i = 0; i < ruleParamList.size(); i++) { - metaDateCodeList.add(ruleParamList.get(i).getMetaDataCode()); - } - //区 考核最终得分计算 - this.assessmentScoreCalculation(kpiRuleDTO.getReferenceId(), - kpiResultSuperiorEntity.getStartDate(),kpiResultSuperiorEntity.getEndDate(), - metaDateCodeList,OrganizationTypeConstant.ORG_TYPE_DISTRICT_DEPT,kpiCycle); - - //街区 考核最终得分计算 - this.assessmentScoreCalculation(kpiRuleDTO.getReferenceId(), - kpiResultSuperiorEntity.getStartDate(),kpiResultSuperiorEntity.getEndDate(), - metaDateCodeList,OrganizationTypeConstant.ORG_TYPE_STREET_DEPT,kpiCycle); - } - return new Result(); + kpiResultSuperiorEntity.setStartDate(startDate); + kpiResultSuperiorEntity.setEndDate(endDate); + kpiResultSuperiorEntity.setKpiCycle(kpiCycle); + kpiResultSuperiorEntity.setFinalScore(BigDecimal.valueOf(score).setScale(NumConstant.TWO, BigDecimal.ROUND_HALF_UP)); + kpiResultSuperiorEntity.setDeptId(deptId); + kpiResultSuperiorEntity.setDeptTypeKey(deptLevelInfo.getTypeKey()); + kpiResultSuperiorEntity.setParentDeptIds(deptLevelInfo.getParentDeptIds()); + kpiResultSuperiorEntity.setParentDeptNames(deptLevelInfo.getParentDeptNames()); + kpiResultSuperiorEntity.setAllDeptIds(deptLevelInfo.getAllDeptIds()); + kpiResultSuperiorEntity.setAllDeptNames(deptLevelInfo.getAllDeptNames()); + kpiResultSuperiorDao.insert(kpiResultSuperiorEntity); } - - /** - * @Description: 根据 区直/街道考核最终得分 JS函数,得出总数 - * @Param: [referenceId] 考核规则表:公式ID - * metaDateCodeList 公式参数表:元数据编码 - * startDate 考核开始时间 - * endDate 考核结束时间 - * typeKey 部门类型 - * String kpiCycle 考核周期 - * @return: BigDecimal - * @Author: zy - * @Date: 2019-12-23 - */ - public Result assessmentScoreCalculation(String referenceId,Date startDate, Date endDate,List metaDateCodeList,String typeKey,String kpiCycle){ - // 根据 考核规则表-外键(公式id),查询绩效考核公式表,待运行公式方法 - KpiFormulaDTO kpiFormulaDTO = kpiFormulaDao.queryFormula(referenceId); - - int pageSize = NumConstant.THIRTY; - int pageIndex = NumConstant.ONE; - - List deptIdList = deptUtils.getDeptIdList(typeKey, pageSize, pageIndex); - do { - - for (Long deptId : deptIdList) { - BigDecimal[] paramValue = selectArrayOfMetaDate(deptId, startDate, endDate, metaDateCodeList); - //参数准备完全时,执行js运算 - if (paramValue.length == kpiFormulaDTO.getParamAmount()) { - BigDecimal calculationScore; - - Result score = this.runJavaScriptFunction(kpiFormulaDTO,paramValue); - calculationScore = score.getData(); - //插入到:街道或区直绩效考核最终得分表 - DeptLevelAndLeaderDTO deptLevelInfo = deptUtils.getDeptLevelInfo(deptId, YesOrNoEnum.YES); - KpiResultSuperiorEntity kpiResultSuperiorEntity = new KpiResultSuperiorEntity(); - kpiResultSuperiorEntity.setStartDate(startDate); - kpiResultSuperiorEntity.setEndDate(endDate); - kpiResultSuperiorEntity.setKpiCycle(kpiCycle); - kpiResultSuperiorEntity.setFinalScore(calculationScore); - kpiResultSuperiorEntity.setDeptId(deptId); - kpiResultSuperiorEntity.setDeptTypeKey(typeKey); - kpiResultSuperiorEntity.setParentDeptIds(deptLevelInfo.getParentDeptIds()); - kpiResultSuperiorEntity.setParentDeptNames(deptLevelInfo.getParentDeptNames()); - kpiResultSuperiorEntity.setAllDeptIds(deptLevelInfo.getAllDeptIds()); - kpiResultSuperiorEntity.setAllDeptNames(deptLevelInfo.getAllDeptNames()); - kpiResultSuperiorDao.insert(kpiResultSuperiorEntity); - } - } - pageIndex++; - deptIdList = deptUtils.getDeptIdList(typeKey, pageSize, pageIndex); - } while (CollUtil.isNotEmpty(deptIdList)); - return new Result(); + + /** + * 获取公式所有参数对应的元数据编码、升序排列 + * + * @param ruleId 规则id + * @return java.util.List + * @author work@yujt.net.cn + * @date 2019/12/25 09:53 + */ + private List getRuleParmOfMetaDateCodeList(String ruleId) { + // 根据 考核规则表-主键,查询公式参数表,排序:1,2,3,4,5 + List ruleParamList = kpiRuleParamDao.queryFormulaParam(ruleId); + List metaDateCodeList = Lists.newArrayList(); + for (int i = 0; i < ruleParamList.size(); i++) { + metaDateCodeList.add(ruleParamList.get(i).getMetaDataCode()); + } + return metaDateCodeList; } /** - * @Description: js函数运行 - * @Param: [kpiFormulaDTO, paramValue] - * @return: com.elink.esua.epdc.commons.tools.utils.Result - * @Author: zy - * @Date: 2019-12-23 + * 初始化javascipt的执行引擎 + * + * @param formula 公式运行方法(Javascript) + * @param ruleCode 规则编码 + * @return javax.script.Invocable + * @author work@yujt.net.cn + * @date 2019/12/24 17:22 */ - public Result runJavaScriptFunction(KpiFormulaDTO kpiFormulaDTO,BigDecimal[] paramValue){ - BigDecimal calculationScore = new BigDecimal(0); + private Invocable initInvocable(String formula, String ruleCode) { + ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); + //执行js代码:参数为:公式运行方法 try { - //获得一个javascipt的执行引擎 - ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); - //执行js代码:参数为:公式运行方法 - engine.eval(kpiFormulaDTO.getFormula()); - //是否可调用方法 - boolean flag = engine instanceof Invocable; - if (!flag) { - return new Result().error("运行方法异常"); - } - Invocable in = (Invocable) engine; - //执行js中的函数 参数:js方法名 + 参数 - Double result = (Double) in.invokeFunction(kpiFormulaDTO.getFunctionName(), paramValue); - Double workScoreDoouble = (double) Math.round(result * 100) / 100; - calculationScore = new BigDecimal(workScoreDoouble); + engine.eval(formula); } catch (Exception e) { - e.printStackTrace(); - return new Result().error("运行方法异常" + e.getMessage()); + logger.error("初始化javascipt执行引擎失败,当前时间:{},考核规则编码:{}", LocalDateTime.now().toString(), ruleCode); + throw new RenException("绩效考核定时任务执行失败1"); + } + // 是否可调用方法 + boolean flag = engine instanceof Invocable; + if (!flag) { + logger.error("初始化javascipt执行引擎失败,当前时间:{},考核规则编码:{}", LocalDateTime.now().toString(), ruleCode); + throw new RenException("绩效考核定时任务执行失败1"); } - return new Result().ok(calculationScore); + return (Invocable) engine; } /** - * 根据月、季、年 以及当前月份,初始化统计元数据值的参数,用于模块间调用 + * 根据公式参数,获取公式参数对应的元数据值 * - * @param kpiCycle 月、季、年 - * @param methodName 调用此方法的方法名,用于日志打印 - * @return java.util.Date 若返回空值:当前月份无法针对传入的考核周期进行考核 - * @author zhangyong - * @date 2019/12/24 + * @param deptId 部门id + * @param startDate 考核周期开始日 + * @param endDate 考核周期结束日 + * @param metaDateCodeList 所有公式参数对应的元数据编码 + * @return java.math.BigDecimal[] + * @author work@yujt.net.cn + * @date 2019/12/25 11:02 */ - private Map initKpiParam(String kpiCycle, String methodName) { - LocalDate startDate = null; - YearMonth now = YearMonth.now(); - if (KpiCycleEnum.KPI_CYCLE_MONTH.getValue().equals(kpiCycle)) { - startDate = now.minusMonths(NumConstant.ONE).atDay(NumConstant.ONE); - } else if (KpiCycleEnum.KPI_CYCLE_QUARTER.getValue().equals(kpiCycle)) { - int monthValue = now.getMonthValue(); - if (monthValue == NumConstant.ONE || monthValue == NumConstant.FOUR || monthValue == NumConstant.SEVEN || monthValue == NumConstant.TEN) { - startDate = now.minusMonths(NumConstant.THREE).atDay(NumConstant.ONE); - } - } else if (KpiCycleEnum.KPI_CYCLE_YEAR.getValue().equals(kpiCycle)) { - if (now.getMonthValue() == NumConstant.ONE) { - startDate = now.minusMonths(NumConstant.TWELVE).atDay(NumConstant.ONE); + private BigDecimal[] selectArrayOfMetaDataValue(Long deptId, Date startDate, Date endDate, List metaDateCodeList) { + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(KpiFieldConstant.START_DATE, startDate) + .eq(KpiFieldConstant.END_DATE, endDate) + .eq(KpiFieldConstant.DEPT_ID, deptId) + .in(KpiFieldConstant.DATA_CODE, metaDateCodeList); + + List metaDataList = kpiMetaDataDao.selectList(wrapper); + BigDecimal[] metaDataValueArray = new BigDecimal[metaDataList.size()]; + + String metaDataCode; + for (int i = 0; i < metaDateCodeList.size(); i++) { + metaDataCode = metaDateCodeList.get(i); + for (KpiMetaDataEntity kpiMetaDataEntity : metaDataList) { + if (kpiMetaDataEntity.getDataCode().equals(metaDataCode)) { + metaDataValueArray[i] = kpiMetaDataEntity.getDataValue(); + } } } - if (null == startDate) { - log.error("当前时间:{},无法按照{}执行绩效考核{}", LocalDateTime.now().toString(), kpiCycle, methodName); - return null; - } - log.info("开始执行:{},当前时间:{},考核周期:{}", methodName, LocalDateTime.now().toString(), kpiCycle); - Map map = new HashMap(); - map.put("startDate", LocalDateUtils.localDateToDate(startDate)); - map.put("endDate", LocalDateUtils.localDateToDate(YearMonth.now().minusMonths(NumConstant.ONE).atEndOfMonth())); - return map; + return metaDataValueArray; } + } diff --git a/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/utils/KpiLocalDateUtils.java b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/utils/KpiLocalDateUtils.java new file mode 100644 index 000000000..97caa4cf2 --- /dev/null +++ b/esua-epdc/epdc-module/epdc-kpi/epdc-kpi-server/src/main/java/com/elink/esua/epdc/utils/KpiLocalDateUtils.java @@ -0,0 +1,47 @@ +package com.elink.esua.epdc.utils; + +import com.elink.esua.epdc.commons.tools.constant.NumConstant; +import com.elink.esua.epdc.commons.tools.utils.LocalDateUtils; +import com.elink.esua.epdc.enums.KpiCycleEnum; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.util.Date; + +/** + * 绩效考核相关日期工具 + * + * @author work@yujt.net.cn + * @date 2019/12/24 17:26 + */ +public class KpiLocalDateUtils { + + /** + * 获取考核周期开始日 + * + * @param kpiCycle 考核周期 月、季、年 + * @return java.util.Date + * @author work@yujt.net.cn + * @date 2019/12/24 17:28 + */ + public static Date getKpiCycoleStartDate(String kpiCycle) { + LocalDate startDate = null; + YearMonth now = YearMonth.now(); + if (KpiCycleEnum.KPI_CYCLE_MONTH.getValue().equals(kpiCycle)) { + startDate = now.minusMonths(NumConstant.ONE).atDay(NumConstant.ONE); + } else if (KpiCycleEnum.KPI_CYCLE_QUARTER.getValue().equals(kpiCycle)) { + int monthValue = now.getMonthValue(); + if (monthValue == NumConstant.ONE || monthValue == NumConstant.FOUR || monthValue == NumConstant.SEVEN || monthValue == NumConstant.TEN) { + startDate = now.minusMonths(NumConstant.THREE).atDay(NumConstant.ONE); + } + } else if (KpiCycleEnum.KPI_CYCLE_YEAR.getValue().equals(kpiCycle)) { + if (now.getMonthValue() == NumConstant.ONE) { + startDate = now.minusMonths(NumConstant.TWELVE).atDay(NumConstant.ONE); + } + } + if (null == startDate) { + return null; + } + return LocalDateUtils.localDateToDate(startDate); + } +}