package cn.fw.morax.service.biz.eval; import cn.fw.common.data.mybatis.pagination.PageData; import cn.fw.common.exception.BusinessException; import cn.fw.common.page.AppPage; import cn.fw.common.web.annotation.DisLock; import cn.fw.common.web.auth.LoginAuthBean; import cn.fw.ehr.sdk.api.result.PostRoleVo; import cn.fw.morax.common.config.FlowVal; import cn.fw.morax.common.utils.MessageFormatUtil; import cn.fw.morax.common.utils.PublicUtil; import cn.fw.morax.domain.db.eval.*; import cn.fw.morax.domain.db.kpi.Indicators; import cn.fw.morax.domain.dto.EvalIndicatorDTO; import cn.fw.morax.domain.dto.query.EvalIndicatorImportQueryDTO; import cn.fw.morax.domain.dto.query.EvalIndicatorQueryDTO; import cn.fw.morax.domain.dto.query.IndicatorPostQueryDTO; import cn.fw.morax.domain.enums.ApplicableTypeEnum; import cn.fw.morax.domain.enums.DataScopeTypeEnum; import cn.fw.morax.domain.enums.IndicatorCodeTypeEnum; import cn.fw.morax.domain.vo.eval.CompositeIndicatorVO; import cn.fw.morax.domain.vo.eval.EvalIndicatorVO; import cn.fw.morax.domain.vo.kpi.IndicatorsVO; import cn.fw.morax.rpc.approval.FlowApproveRpc; import cn.fw.morax.rpc.ehr.EhrRpcService; import cn.fw.morax.rpc.ehr.dto.PostInfoDTO; import cn.fw.morax.service.biz.CommonService; import cn.fw.morax.service.biz.kpi.KpiGroupUserBizService; import cn.fw.morax.service.data.ApprovalRecordService; import cn.fw.morax.service.data.eval.*; import cn.fw.morax.service.data.kpi.IndicatorsService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.common.collect.Lists; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; import static cn.fw.common.businessvalidator.Validator.BV; @Service @Slf4j @RequiredArgsConstructor public class EvalIndicatorBizService { private final EvalIndicatorService evalIndicatorService; private final IndicatorsService indicatorsService; private final CommonService commonService; private final EhrRpcService ehrRpcService; @Value("${spring.cache.custom.global-prefix}:eval:indicator:save:") @Getter private String savePrefix; @Value("${spring.cache.custom.global-prefix}:eval:indicator:enable:") @Getter private String enablePrefix; @Value("${spring.cache.custom.global-prefix}:eval:group:save:") @Getter private String saveGroupPrefix; /** * 分页查询 * * @param dto * @return */ public AppPage evalIndicatorPage(EvalIndicatorQueryDTO dto) { PageData pageData = evalIndicatorService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()), Wrappers.lambdaQuery() .eq(PublicUtil.isNotEmpty(dto.getSysId()), EvalIndicator::getSysId, dto.getSysId()) .eq(PublicUtil.isNotEmpty(dto.getRoleCode()), EvalIndicator::getRoleCode, dto.getRoleCode()) .eq(PublicUtil.isNotEmpty(dto.getEnable()), EvalIndicator::getEnable, dto.getEnable()) .and(PublicUtil.isNotEmpty(dto.getKeyword()), w -> w.like(EvalIndicator::getCode, dto.getKeyword()).or().like(EvalIndicator::getName, dto.getKeyword()) ) .eq(EvalIndicator::getYn, Boolean.TRUE) ); return PublicUtil.toPage(pageData, evalIndicator -> { EvalIndicatorVO evalIndicatorVO = PublicUtil.copy(evalIndicator, EvalIndicatorVO.class); return evalIndicatorVO; }); } /** * 考评指标详情 * * @param id * @return */ public EvalIndicatorVO evalIndicatorDetail(Long id) { EvalIndicator evalIndicator = evalIndicatorService.getById(id); return PublicUtil.copy(evalIndicator, EvalIndicatorVO.class); } /** * 启用禁用指标 * * @param indicatorId * @param enable */ @Transactional(rollbackFor = Exception.class) @DisLock(prefix = "#this.getEnablePrefix()", key = "#indicatorId", message = "修改中,请勿重复操作") public void enableIndicator(Long indicatorId, Boolean enable) { EvalIndicator evalIndicator = evalIndicatorService.getById(indicatorId); BV.notNull(evalIndicator, "指标不存在,请重试"); BV.isFalse(enable.equals(evalIndicator.getEnable()), "指标已经是" + ((enable) ? "启用" : "禁用") + "状态,请重试"); //禁用情况:正在使用的指标不能禁用,并提示哪些地方在用 // if (! enable) { // List kpiGroups = evalIndicatorService.getEvalGroupByIndicatorId(indicatorId); // Set postNames = kpiGroups.stream().map(KpiGroup::getPostName).collect(Collectors.toSet()); // if (PublicUtil.isNotEmpty(postNames)) { // throw new BusinessException(String.join(",", postNames) + "岗位正在使用此绩效指标,不能禁用"); // } // } evalIndicatorService.update(Wrappers.lambdaUpdate() .set(EvalIndicator::getEnable, enable) .set(EvalIndicator::getUpdateTime, new Date()) .eq(EvalIndicator::getId, indicatorId) ); } /** * 保存 * * @param dto * @param user * @return */ @Transactional(rollbackFor = Exception.class) @DisLock(prefix = "#this.getSavePrefix()", key = "#dto.getName()", message = "保存中,请勿重复操作") public void saveEvalIndicator(EvalIndicatorDTO dto, LoginAuthBean user) { checkDto(dto); checkIndicatorName(dto.getId(), dto.getName()); EvalIndicator evalIndicator = this.convertToDB(dto); if (PublicUtil.isEmpty(dto.getId())) { String indicatorCode = PublicUtil.getUUID(); this.checkIndicatorCode(indicatorCode); evalIndicator.setCode(indicatorCode); } else { EvalIndicator originEvalIndicator = evalIndicatorService.getById(dto.getId()); BV.notNull(evalIndicator, "指标不存在,请重试"); evalIndicator.setCode(originEvalIndicator.getCode()); evalIndicator.setId(originEvalIndicator.getId()); evalIndicator.setEnable(originEvalIndicator.getEnable()); } evalIndicatorService.saveOrUpdate(evalIndicator); } /** * 检查指标编码 * * @param code */ private void checkIndicatorCode(String code) { long taskCount = evalIndicatorService.count(Wrappers.lambdaQuery() .eq(EvalIndicator::getCode, code) ); if (taskCount > 0) { log.error("指标编码生成重复:{}", code); throw new BusinessException("指标编码已存在,请重试"); } } /** * 检查指标名称 * * @param indicatorName */ private void checkIndicatorName(Long id, String indicatorName) { long taskCount = evalIndicatorService.count(Wrappers.lambdaQuery() .eq(EvalIndicator::getName, indicatorName) .eq(EvalIndicator::getYn, Boolean.TRUE) .ne(PublicUtil.isNotEmpty(id), EvalIndicator::getId, id) ); BV.isFalse(taskCount > 0, "指标名称已存在,请重新输入"); } /** * 检查指标参数 * 1. 滚动天数 滚动天数,开始日期 * 2. 按星期 频率值 * 3. 按月指定日期 频率值 * 4. 按滚动月 滚动月数、滚动天数、开始日期、按滚动月计算顺序 * * @param dto */ private void checkDto(EvalIndicatorDTO dto) { Boolean paramError; switch (dto.getRuleType()) { case DAY: //rule_values(滚动天数),start_time(开始日期) if (PublicUtil.isEmpty(dto.getStartTime()) || PublicUtil.isEmpty(dto.getRollValue())) { throw new BusinessException("开始日期、滚动值不能为空"); } break; case WEEK_DAY: //rule_values(频率值) if (PublicUtil.isEmpty(dto.getRuleValues())) { throw new BusinessException("指定星期不能为空"); } paramError = dto.getRuleValues().stream().filter(value -> (value > 7 || value < 1)).findFirst().isPresent(); BV.isFalse(paramError, "指定星期参数异常"); break; case MONTH_FIX_DAY: //rule_values(频率值) if (PublicUtil.isEmpty(dto.getRuleValues())) { throw new BusinessException("指定日期不能为空"); } paramError = dto.getRuleValues().stream().filter(value -> (value > 31 || value < 1)).findFirst().isPresent(); BV.isFalse(paramError, "按月指定日期参数异常"); break; case MONTH: //滚动月数、滚动天数、开始日期、按滚动月计算顺序 //rule_values(滚动月数、滚动开始日),start_time(开始日期),order_type(按滚动月计算顺序) if (PublicUtil.isEmpty(dto.getOrderType()) || PublicUtil.isEmpty(dto.getRuleValues()) || PublicUtil.isEmpty(dto.getRollValue()) || PublicUtil.isEmpty(dto.getStartTime())) { throw new BusinessException("开始日期、滚动值不能为空"); } if (dto.getRollValue() > 31 || dto.getRollValue() < 1) { throw new BusinessException("滚动天不能大于31或小于1"); } paramError = dto.getRuleValues().stream().filter(value -> (value > 31 || value < 1)).findFirst().isPresent(); BV.isFalse(paramError, "滚动月开始日错误"); break; } } /** * 转换为db对象 * * 1. 滚动天数 rollValue(滚动天),startTime(开始日期) * 2. 按星期 ruleValues(星期) * 3. 按月指定日期 ruleValues(滚动月数、滚动开始日) * 4. 按滚动月 ruleValues(滚动月数),startTime(开始日期), * orderType(按滚动月计算顺序), rollValue(滚动天) * @return */ public EvalIndicator convertToDB(EvalIndicatorDTO dto){ EvalIndicator indicators = EvalIndicator.builder() .name(dto.getName()) .enable(Boolean.TRUE) .ruleType(dto.getRuleType()) .dataType(dto.getDataType()) .targetType(dto.getTargetType()) // .sysId(dto.getSysId()) // .sysName(dto.getSysName()) .roleCode(dto.getRoleCode()) .roleName(dto.getRoleName()) .build(); if (PublicUtil.isEmpty(dto.getId())) { indicators.setId(dto.getId()); } //频率类型; 1:按滚动天 2:按星期 3:按月指定日期 4:按滚动月 switch (dto.getRuleType()) { case DAY: { indicators.setStartTime(dto.getStartTime()); // indicators.setRuleValues(new ArrayList(){{add(dto.getRollValue());}}); indicators.setRollValue(dto.getRollValue()); break; } case WEEK_DAY: case MONTH_FIX_DAY: { indicators.setRuleValues(dto.getRuleValues()); break; } case MONTH: { indicators.setOrderType(dto.getOrderType()); indicators.setStartTime(dto.getStartTime()); indicators.setRuleValues(dto.getRuleValues()); indicators.setRollValue(dto.getRollValue()); // indicators.setRuleValues(new ArrayList(){{add(dto.getRollValue());}}); break; } } return indicators; } /** * 查询岗位指标 * * @param postId * @param applicableType * @return */ public List getPostIndicators(Long postId, ApplicableTypeEnum applicableType) { List evalIndicators = evalIndicatorService.list(Wrappers.lambdaQuery() .eq(EvalIndicator::getYn, Boolean.TRUE) .eq(EvalIndicator::getEnable, Boolean.TRUE) ); List postIds = new ArrayList(){{add(postId);}}; List postInfoDTOS = ehrRpcService.getPostInfoList(postIds); List roleCodes = postInfoDTOS.stream() .map(PostInfoDTO::getRoleList) .filter(Objects::nonNull) .flatMap(Collection::stream) .map(PostRoleVo::getRoleCode) .distinct().collect(Collectors.toList()); Boolean queryManagerRole = commonService.hasManagerRole(roleCodes); IndicatorPostQueryDTO dto = new IndicatorPostQueryDTO(roleCodes, queryManagerRole); dto.setApplicableType(applicableType); List indicatorsVOS = indicatorsService.getPostIndicators(dto); List compositeIndicators = Lists.newArrayListWithCapacity(evalIndicators.size() + indicatorsVOS.size()); for (EvalIndicator evalIndicator : evalIndicators) { compositeIndicators.add(convertVO(evalIndicator)); } for (IndicatorsVO indicators : indicatorsVOS) { compositeIndicators.add(convertVO(indicators)); } return compositeIndicators; } /** * 查询岗位指标 * * @param applicableType * @return */ public List getShopIndicators(ApplicableTypeEnum applicableType) { List evalIndicators = evalIndicatorService.list(Wrappers.lambdaQuery() .eq(EvalIndicator::getYn, Boolean.TRUE) .eq(EvalIndicator::getEnable, Boolean.TRUE) ); List kpiIndicators = indicatorsService.list(Wrappers.lambdaQuery() .eq(Indicators::getYn, Boolean.TRUE) .eq(Indicators::getEnable, Boolean.TRUE) .apply(MessageFormatUtil.transferWithQuotationMarks("FIND_IN_SET({0}, apply_types)", applicableType.getValue())) .apply(MessageFormatUtil.transferWithQuotationMarks("FIND_IN_SET({0}, data_scope_types)", DataScopeTypeEnum.SHOP.getValue())) ); List compositeIndicators = Lists.newArrayListWithCapacity(evalIndicators.size() + kpiIndicators.size()); for (EvalIndicator evalIndicator : evalIndicators) { compositeIndicators.add(convertVO(evalIndicator)); } for (Indicators indicators : kpiIndicators) { IndicatorsVO indicatorsVO = PublicUtil.copy(indicators, IndicatorsVO.class); compositeIndicators.add(convertVO(indicatorsVO)); } return compositeIndicators; } public CompositeIndicatorVO convertVO(EvalIndicator evalIndicator) { CompositeIndicatorVO compositeIndicator = new CompositeIndicatorVO(); compositeIndicator.setSId(IndicatorCodeTypeEnum.EVAL_INDICATOR.getValue() + "_" + evalIndicator.getId()); compositeIndicator.setId(evalIndicator.getId()); compositeIndicator.setCodeType(IndicatorCodeTypeEnum.EVAL_INDICATOR); compositeIndicator.setCode(evalIndicator.getCode()); compositeIndicator.setName(evalIndicator.getName()); if (PublicUtil.isNotEmpty(evalIndicator.getSysId())) { compositeIndicator.setSysId(evalIndicator.getSysId()); compositeIndicator.setSysPrefix(evalIndicator.getSysPrefix()); compositeIndicator.setSysName(evalIndicator.getSysName()); } compositeIndicator.setRoleCode(evalIndicator.getRoleCode()); compositeIndicator.setRoleName(evalIndicator.getRoleName()); compositeIndicator.setDataType(evalIndicator.getDataType()); compositeIndicator.setRuleType(evalIndicator.getRuleType()); compositeIndicator.setRollValue(evalIndicator.getRollValue()); compositeIndicator.setRuleValues(evalIndicator.getRuleValues()); compositeIndicator.setOrderType(evalIndicator.getOrderType()); compositeIndicator.setStartTime(evalIndicator.getStartTime()); compositeIndicator.setTargetType(evalIndicator.getTargetType()); compositeIndicator.setEnable(evalIndicator.getEnable()); return compositeIndicator; } public CompositeIndicatorVO convertVO(IndicatorsVO indicators) { CompositeIndicatorVO compositeIndicator = new CompositeIndicatorVO(); compositeIndicator.setSId(IndicatorCodeTypeEnum.INDICATOR.getValue() + "_" + indicators.getId()); compositeIndicator.setId(indicators.getId()); compositeIndicator.setCodeType(IndicatorCodeTypeEnum.INDICATOR); compositeIndicator.setCode(indicators.getIndicatorCode()); compositeIndicator.setName(indicators.getIndicatorName()); compositeIndicator.setSysId(indicators.getSysId()); compositeIndicator.setSysPrefix(indicators.getSysPrefix()); compositeIndicator.setSysName(indicators.getSysName()); compositeIndicator.setDataType(indicators.getDataType()); compositeIndicator.setTargetType(indicators.getTargetType()); compositeIndicator.setEnable(indicators.getEnable()); return compositeIndicator; } public List getEvalIndicators() { List evalIndicators = evalIndicatorService.list(Wrappers.lambdaQuery() .eq(EvalIndicator::getYn, Boolean.TRUE) .eq(EvalIndicator::getEnable, Boolean.TRUE) ); return PublicUtil.copyList(evalIndicators, EvalIndicatorVO.class); } }