CombineIndicatorBizService.java 19.9 KB
package cn.fw.morax.service.biz.kpi;

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.morax.common.utils.PublicUtil;
import cn.fw.morax.domain.db.CombineIndicator;
import cn.fw.morax.domain.db.CombineIndicatorParam;
import cn.fw.morax.domain.db.eval.EvalIndicator;
import cn.fw.morax.domain.db.kpi.Indicators;
import cn.fw.morax.domain.dto.CombineIndicatorDTO;
import cn.fw.morax.domain.dto.query.CombineIndicatorQueryDTO;
import cn.fw.morax.domain.enums.*;
import cn.fw.morax.domain.vo.CombineAndEvalIndicatorVO;
import cn.fw.morax.domain.vo.CombineIndicatorParamVO;
import cn.fw.morax.domain.vo.CombineIndicatorVO;
import cn.fw.morax.domain.vo.eval.CompositeIndicatorVO;
import cn.fw.morax.domain.vo.eval.EvalIndicatorVO;
import cn.fw.morax.domain.vo.kpi.IndicatorsAndEvalIndicatorsVO;
import cn.fw.morax.domain.vo.kpi.IndicatorsVO;
import cn.fw.morax.service.data.CombineIndicatorParamService;
import cn.fw.morax.service.data.CombineIndicatorService;
import cn.fw.morax.service.data.eval.EvalIndicatorService;
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.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static cn.fw.common.businessvalidator.Validator.BV;

/**
 * @author jiangchao
 * @des: 组合指标配置
 * @date 2023/3/27 16:00
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class CombineIndicatorBizService {

    private final IndicatorsService indicatorsService;
    private final EvalIndicatorService evalIndicatorService;
    private final CombineIndicatorService combineIndicatorService;
    private final CombineIndicatorParamService combineIndicatorParamService;
    @Value("${spring.cache.custom.global-prefix}:combine:save:")
    @Getter
    private String savePrefix;
    @Value("${spring.cache.custom.global-prefix}:combine:enable:")
    @Getter
    private String enablePrefix;

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    public List<CombineAndEvalIndicatorVO> combineAndEvalIndicators(CombineIndicatorQueryDTO dto) {

        List<CombineAndEvalIndicatorVO> combineAndEvalIndicatorVOS = Lists.newArrayListWithCapacity(100);
        if (PublicUtil.isEmpty(dto.getCombineIndicator()) || Boolean.FALSE.equals(dto.getCombineIndicator())) {
            List<EvalIndicator> evalIndicators = evalIndicatorService.list(Wrappers.<EvalIndicator>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.getHasTarget()), w ->{
                        if (Boolean.TRUE.equals(dto.getHasTarget())) {
                            w.ne(EvalIndicator::getTargetType, TargetTypeEnum.NO);
                        } else {
                            w.eq(EvalIndicator::getTargetType, TargetTypeEnum.NO);
                        }
                    })
                    .and(PublicUtil.isNotEmpty(dto.getKeyword()), w ->
                            w.like(EvalIndicator::getCode, dto.getKeyword()).or().like(EvalIndicator::getName, dto.getKeyword())
                    )
                    .eq(EvalIndicator::getYn, Boolean.TRUE)
            );
            if (PublicUtil.isNotEmpty(evalIndicators)) {
                for (EvalIndicator evalIndicator : evalIndicators) {
                    CombineAndEvalIndicatorVO indicatorVO = PublicUtil.copy(evalIndicator, CombineAndEvalIndicatorVO.class);
                    indicatorVO.setCodeType(IndicatorCodeTypeEnum.EVAL_INDICATOR);
                    combineAndEvalIndicatorVOS.add(indicatorVO);
                }
            }
        }

        //目标、角色都是针对考评指标的搜索
        if (PublicUtil.isNotEmpty(dto.getHasTarget()) || PublicUtil.isNotEmpty(dto.getRoleCode())) {
            return combineAndEvalIndicatorVOS;
        }

        if (PublicUtil.isEmpty(dto.getCombineIndicator()) || Boolean.TRUE.equals(dto.getCombineIndicator())) {
            List<CombineIndicator> combineIndicators = combineIndicatorService.list(Wrappers.<CombineIndicator>lambdaQuery()
                    .eq(CombineIndicator::getGroupId, dto.getGroupId())
                    .eq(PublicUtil.isNotEmpty(dto.getEnable()), CombineIndicator::getEnable, dto.getEnable())
                    //支持指标名称和编码的模糊查询
                    .and(PublicUtil.isNotEmpty(dto.getKeyword()),
                    wrapper -> wrapper.like(CombineIndicator::getCombineCode, dto.getKeyword())
                            .or()
                            .like(CombineIndicator::getName, dto.getKeyword())
                    )
                    .eq(CombineIndicator::getYn, Boolean.TRUE)
            );
            if (PublicUtil.isNotEmpty(combineIndicators)) {
                Map<Long, List<CombineIndicatorParam>> combineParamMap = getCombineNameMap(combineIndicators);
                for (CombineIndicator combineIndicator : combineIndicators) {
                    List<String> combineIndicatorNames = combineParamMap.getOrDefault(combineIndicator.getId(), new ArrayList<>()).stream()
                            .map(CombineIndicatorParam::getName).collect(Collectors.toList());
                    CombineAndEvalIndicatorVO indicatorVO = PublicUtil.copy(combineIndicator, CombineAndEvalIndicatorVO.class);
                    indicatorVO.setCombineIndicatorNames(combineIndicatorNames);
                    indicatorVO.setCode(combineIndicator.getCombineCode());
                    indicatorVO.setCodeType(IndicatorCodeTypeEnum.COMBINE_INDICATOR);
                    combineAndEvalIndicatorVOS.add(indicatorVO);
                }
            }
        }

        return combineAndEvalIndicatorVOS;
    }

    public Map<Long, List<CombineIndicatorParam>> getCombineNameMap(List<CombineIndicator> combineIndicators) {
        List<Long> combineIndicatorIds = combineIndicators.stream().map(CombineIndicator::getId).collect(Collectors.toList());
        List<CombineIndicatorParam> params = combineIndicatorParamService.list(Wrappers.<CombineIndicatorParam>lambdaQuery()
                .in(CombineIndicatorParam::getCombineIndicatorId, combineIndicatorIds)
                .eq(CombineIndicatorParam::getYn, Boolean.TRUE)
        );
        Map<Long ,List<CombineIndicatorParam>> combineParamMap = params.stream().collect(Collectors.groupingBy(CombineIndicatorParam::getCombineIndicatorId));
        return combineParamMap;
    }

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    public AppPage<CombineIndicatorVO> page(CombineIndicatorQueryDTO dto) {
        PageData<CombineIndicator> pageData = combineIndicatorService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()),
                Wrappers.<CombineIndicator>lambdaQuery()
                        .eq(CombineIndicator::getGroupId, dto.getGroupId())
                        .eq(PublicUtil.isNotEmpty(dto.getEnable()), CombineIndicator::getEnable, dto.getEnable())
                        .eq(CombineIndicator::getYn, Boolean.TRUE)
                        //支持指标名称和编码的模糊查询
                        .and(PublicUtil.isNotEmpty(dto.getKeyword()),
                                wrapper -> wrapper.like(CombineIndicator::getCombineCode,dto.getKeyword())
                                .or()
                                .like(CombineIndicator::getName, dto.getKeyword())
                                )
        );

        List<CombineIndicatorParam> indicatorParamList = null;
        if (!CollectionUtils.isEmpty(pageData.getRecords())){
            List<Long> ids = pageData.getRecords().stream().map(e -> e.getId()).collect(Collectors.toList());
             indicatorParamList = combineIndicatorParamService.list(Wrappers.<CombineIndicatorParam>lambdaQuery()
                    .in(CombineIndicatorParam::getCombineIndicatorId, ids));
        }

        List<CombineIndicatorParam> finalIndicatorParamList = indicatorParamList;
        return PublicUtil.toPage(pageData, combineIndicator -> {
            CombineIndicatorVO indicatorVO = PublicUtil.copy(combineIndicator, CombineIndicatorVO.class);
            if (!CollectionUtils.isEmpty(finalIndicatorParamList)){
                List<CombineIndicatorParam> combineIndicatorParams = finalIndicatorParamList.stream().filter(f -> f.getCombineIndicatorId().equals(indicatorVO.getId())).collect(Collectors.toList());
                //前端需要这个详情返回,做处理
                indicatorVO.setCombineIndicatorParams(PublicUtil.copyList(combineIndicatorParams, CombineIndicatorParamVO.class));
            }
            return indicatorVO;
        });
    }

    public CombineIndicatorVO detail(Long id) {
        CombineIndicator combineIndicator = combineIndicatorService.getById(id);
        BV.notNull(combineIndicator, "配置不存在,请重试");
        CombineIndicatorVO combineIndicatorVO = PublicUtil.copy(combineIndicator, CombineIndicatorVO.class);
        //调试完删除,用下面第一或者第二写法
        //List<IndicatorsVO> indicators = combineIndicatorParamService.queryByCombineId(id);
        //combineIndicatorVO.setIndicators(indicators);
        //下面组合查询待验证[第一种写法,sql union 聚合相同字段,非相同字段兼容不了]
        List<IndicatorsAndEvalIndicatorsVO> andEvalIndicatorsVOS = combineIndicatorParamService.queryIndicatorsAndEvalIndicatorsByCombineId(id);
        combineIndicatorVO.setIndicators(andEvalIndicatorsVOS);
        //第二种写法,查询后再组装,[可以组装全部完整字段]
        //List<IndicatorsAndEvalIndicatorsVO> evalIndicatorsVOS = queryByCodeTypeUnion(id);
        //combineIndicatorVO.setAndEvalIndicatorsVOS(evalIndicatorsVOS);

        return combineIndicatorVO;
    }


    /**
     * 聚合不同   `code_type` tinyint(4) NOT NULL COMMENT '指标类型(1.指标,2,考评指标)', 的完整数据
     * @param id
     * @return
     */
    public List<IndicatorsAndEvalIndicatorsVO> queryByCodeTypeUnion(Long id){
        List<IndicatorsAndEvalIndicatorsVO> res = new ArrayList<>();
        List<CombineIndicatorParam> list = combineIndicatorParamService.list(Wrappers.<CombineIndicatorParam>lambdaQuery().eq(CombineIndicatorParam::getCombineIndicatorId, id));
        if (!CollectionUtils.isEmpty(list)){
            Map<IndicatorCodeTypeEnum, List<CombineIndicatorParam>> listMap = list.stream().collect(Collectors.groupingBy(CombineIndicatorParam::getCodeType));
            for (IndicatorCodeTypeEnum codeTypeEnum : listMap.keySet()) {
                if (codeTypeEnum.equals(IndicatorCodeTypeEnum.INDICATOR)){
                    //完整数据对应 indicators 表
                    List<CombineIndicatorParam> indicatorParamList = listMap.get(codeTypeEnum);
                    Set<String> stringCodeSet = indicatorParamList.stream().map(CombineIndicatorParam::getCode).collect(Collectors.toSet());
                    List<Indicators> indicatorsList = indicatorsService.list(Wrappers.<Indicators>lambdaQuery().in(Indicators::getIndicatorCode, stringCodeSet));
                    for (CombineIndicatorParam combineIndicatorParam : indicatorParamList) {
                        Optional<Indicators> first = indicatorsList.stream().filter(e -> e.getIndicatorCode().equals(combineIndicatorParam.getCode())).findFirst();
                        if (first.isPresent()){
                            Indicators indicators = first.get();
                            IndicatorsAndEvalIndicatorsVO vo = new IndicatorsAndEvalIndicatorsVO();
                            BeanUtils.copyProperties(indicators, vo);
                            vo.setCode(combineIndicatorParam.getCode());
                            vo.setName(combineIndicatorParam.getName());
                            vo.setCodeType(combineIndicatorParam.getCodeType());
                            res.add(vo);
                        }
                    }
                }
                if (codeTypeEnum.equals(IndicatorCodeTypeEnum.EVAL_INDICATOR)){
                    //完整数据对应 eval_indicator 表
                    List<CombineIndicatorParam> indicatorParamList = listMap.get(codeTypeEnum);
                    Set<String> stringCodeSet = indicatorParamList.stream().map(CombineIndicatorParam::getCode).collect(Collectors.toSet());
                    List<EvalIndicator> indicatorsList = evalIndicatorService.list(Wrappers.<EvalIndicator>lambdaQuery().in(EvalIndicator::getCode, stringCodeSet));
                    for (CombineIndicatorParam combineIndicatorParam : indicatorParamList) {
                        Optional<EvalIndicator> first = indicatorsList.stream().filter(e -> e.getCode().equals(combineIndicatorParam.getCode())).findFirst();
                        if (first.isPresent()){
                            EvalIndicator evalIndicator = first.get();
                            IndicatorsAndEvalIndicatorsVO vo = new IndicatorsAndEvalIndicatorsVO();
                            BeanUtils.copyProperties(evalIndicator, vo);
                            vo.setCode(combineIndicatorParam.getCode());
                            vo.setName(combineIndicatorParam.getName());
                            vo.setCodeType(combineIndicatorParam.getCodeType());
                            res.add(vo);
                        }
                    }
                }
            }
        }
        return res;
    }



    @Transactional(rollbackFor = Exception.class)
    @DisLock(prefix = "#this.getSavePrefix()", key = "#dto.getName()", message = "保存中,请勿重复操作")
    public void save(CombineIndicatorDTO dto) {
        checkDto(dto);
        removeOldData(dto);

        CombineIndicator combineIndicator = convertDB(dto);
        combineIndicatorService.saveOrUpdate(combineIndicator);
        final Long combineIndicatorId = combineIndicator.getId();

        List<CombineIndicatorParam> params = PublicUtil.copyList(dto.getIndicators(), CombineIndicatorParam.class);
        params.forEach(param -> param.setCombineIndicatorId(combineIndicatorId));
        combineIndicatorParamService.saveBatch(params);
    }

    /**
     * 组合指标库禁用启用
     *
     * @param id
     * @param enable
     */
    @Transactional(rollbackFor = Exception.class)
    @DisLock(prefix = "#this.getEnablePrefix()", key = "#indicatorId", message = "修改中,请勿重复操作")
    public void enableCombineIndicator(Long id, Boolean enable) {
        CombineIndicator combineIndicator = combineIndicatorService.getById(id);
        BV.notNull(combineIndicator, "组合指标不存在,请重试");
        BV.isFalse(enable.equals(combineIndicator.getEnable()), "指标已经是" + ((enable) ? "启用" : "禁用") + "状态,请重试");
        combineIndicatorService.update(Wrappers.<CombineIndicator>lambdaUpdate()
                .set(CombineIndicator::getEnable, enable)
                .eq(CombineIndicator::getId, id)
        );
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeOldData(CombineIndicatorDTO dto) {
        if (PublicUtil.isNotEmpty(dto.getId())) {
            List<CombineIndicatorParam> params = combineIndicatorParamService.list(Wrappers.<CombineIndicatorParam>lambdaUpdate()
                    .eq(CombineIndicatorParam::getCombineIndicatorId, dto.getId()));
            combineIndicatorParamService.removeByIds(params.stream().map(CombineIndicatorParam::getId).collect(Collectors.toList()));
        }
    }

    public void checkDto(CombineIndicatorDTO dto) {
        List<CombineIndicator> combineIndicators = combineIndicatorService.list(Wrappers.<CombineIndicator>lambdaUpdate()
                .ne(PublicUtil.isNotEmpty(dto.getId()), CombineIndicator::getId, dto.getId())
                .eq(CombineIndicator::getName, dto.getName())
                .eq(CombineIndicator::getGroupId, dto.getGroupId())
                .eq(CombineIndicator::getYn, Boolean.TRUE)
        );
        if (PublicUtil.isNotEmpty(combineIndicators)) {
            throw new BusinessException("组合指标名称重复,请重新输入");
        }
    }

    public CombineIndicator convertDB(CombineIndicatorDTO dto) {
        CombineIndicator combineIndicator = new CombineIndicator();
        if (PublicUtil.isNotEmpty(dto.getId())) {
            combineIndicator.setId(dto.getId());
        }
        combineIndicator.setCombineCode(dto.getCombineCode());
        combineIndicator.setName(dto.getName());
        combineIndicator.setLaddersType(dto.getLaddersType());
        List<Integer> dataScopeTypes = dto.getDataScopeTypes().stream().map(DataScopeTypeEnum::getValue)
                .collect(Collectors.toList());
        combineIndicator.setDataScopeTypes(dataScopeTypes);
        //如果有考评指标就是  考评指标组合
        Boolean hasEvalIndicator = dto.getIndicators().stream()
                .filter(param -> IndicatorCodeTypeEnum.EVAL_INDICATOR.equals(param.getCodeType()))
                .findAny().isPresent();
        CombineIndicatorTypeEnum type = hasEvalIndicator ? CombineIndicatorTypeEnum.EVAL_INDICATOR : CombineIndicatorTypeEnum.INDICATOR;
        combineIndicator.setCombineType(type);
        combineIndicator.setCombineCode(Optional.ofNullable(dto.getCombineCode()).orElse(PublicUtil.getUUID()));
        combineIndicator.setEnable(Optional.ofNullable(dto.getEnable()).orElse(Boolean.TRUE));
        combineIndicator.setYn(Boolean.TRUE);
        combineIndicator.setGroupId(dto.getGroupId());
        return combineIndicator;
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeById(Long id) {
        combineIndicatorService.removeById(id);
        combineIndicatorParamService.update(Wrappers.<CombineIndicatorParam>lambdaUpdate()
                .eq(CombineIndicatorParam::getCombineIndicatorId, id)
                .set(CombineIndicatorParam::getYn, Boolean.FALSE)
        );
    }

    /**
     * 查询岗位指标
     *
     * @param postId
     * @param applicableType
     * @return
     */
    public List<CompositeIndicatorVO> getPostIndicators(Long postId, ApplicableTypeEnum applicableType) {
        List<EvalIndicator> evalIndicators = evalIndicatorService.list(Wrappers.<EvalIndicator>lambdaQuery()
                .eq(EvalIndicator::getYn, Boolean.TRUE)
                .eq(EvalIndicator::getEnable, Boolean.TRUE)
        );

//        List<Long> postIds = new ArrayList<Long>(){{add(postId);}};
//        List<PostInfoDTO> postInfoDTOS = ehrRpcService.getPostInfoList(postIds);
//        List<String> 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<IndicatorsVO> indicatorsVOS = indicatorsService.getPostIndicators(dto);
//
//        List<CompositeIndicatorVO> 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;
        return null;
    }


}