CommonService.java 14.6 KB
package cn.fw.morax.service.biz;

import cn.fw.common.exception.BusinessException;
import cn.fw.ehr.sdk.api.enums.RoleManagerEnum;
import cn.fw.morax.common.constant.Constant;
import cn.fw.morax.common.utils.ExcelDataUtil;
import cn.fw.morax.common.utils.PublicUtil;
import cn.fw.morax.domain.db.SettingDraft;
import cn.fw.morax.domain.db.eval.EvalGroupRewardRankLog;
import cn.fw.morax.domain.db.eval.EvalIndicatorValue;
import cn.fw.morax.domain.db.kpi.IndicatorUserValue;
import cn.fw.morax.domain.db.kpi.KpiGroup;
import cn.fw.morax.domain.dto.AbstractLaddersDto;
import cn.fw.morax.domain.enums.DataTypeEnum;
import cn.fw.morax.domain.enums.IndicatorValueTypeEnum;
import cn.fw.morax.domain.enums.SettingDraftStatusEnum;
import cn.fw.morax.domain.enums.SettingDraftTypeEnum;
import cn.fw.morax.domain.vo.kpi.IndicatorUserValueVO;
import cn.fw.morax.domain.vo.kpi.KpiIndicatorRankStaffVO;
import cn.fw.morax.rpc.ehr.EhrRpcService;
import cn.fw.morax.rpc.ehr.dto.StaffBaseInfoDTO;
import cn.fw.morax.service.data.SettingDraftService;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class CommonService {

    private final EhrRpcService ehrRpcService;
    private final SettingDraftService settingDraftService;

    /**
     * 检查阶梯
     *
     * @param dtos
     */
    public static void checkLadders(List<? extends AbstractLaddersDto> dtos) {
        if (PublicUtil.isEmpty(dtos)) {
            return;
        }
        String errorPromptName = dtos.get(0).getBusinessName();
        checkLadders(dtos, errorPromptName);
    }

    /**
     * 检查阶梯
     *
     * @param dtos
     */
    public static void checkLadders(List<? extends AbstractLaddersDto> dtos, String errorPromptName) {
        if (PublicUtil.isEmpty(dtos)) {
            return;
        }
        BigDecimal lastUpper = null;
        //阶梯值校验  标准分不能超过指标基础分,阶梯值必须连续
        for (AbstractLaddersDto laddersDto : dtos) {
            BigDecimal lower = laddersDto.getLower();
            BigDecimal upper = laddersDto.getUpper();
            //上一条的下限要等于下一条的上限
            if (PublicUtil.isNotEmpty(lastUpper) && (lastUpper.compareTo(lower) != 0) ) {
                throw new BusinessException("【" + errorPromptName + "】的阶梯上限与下限不是连续,请编辑后重试");
            }
            //每条上限大于下限
            if (lower.compareTo(upper) >= 0) {
                throw new BusinessException("【" + errorPromptName + "】的阶梯下限大于或等于阶梯上限,请修改错误阶梯");
            }
            lastUpper = laddersDto.getUpper();
        }
    }


    /**
     * 导出文件
     *
     * @param response
     * @param rows
     * @param fileName
     */
    public static <T> void downloadExcel(HttpServletResponse response, List<T> rows, String fileName, Class<?> source) {
        ExcelWriter writer = ExcelUtil.getWriter();
        ExcelDataUtil.setExcelHeadAndWidth(writer, source, Boolean.TRUE);
        writer.setOnlyAlias(true);
        writer.write(rows, true);
        ExcelDataUtil.setAutoSizeColumn(writer.getSheet());
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName);
        ServletOutputStream out= null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 导出文件
     *
     * @param response
     * @param fileName
     */
    public static <T> void downloadTemplateExcel(HttpServletResponse response, String fileName, Class<?> source) {
        ExcelWriter writer = ExcelUtil.getWriter();
        Map<String, String> headMap = ExcelDataUtil.setExcelHeadAndWidth(writer, source, Boolean.FALSE);
        if (headMap.isEmpty()) {
            return;
        }
        writer.writeHeadRow(headMap.values());
        writer.setRowHeight(0, 25);
//        ExcelDataUtil.setAutoSizeColumn(writer.getSheet(), headMap.size());
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName);
        ServletOutputStream out= null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 获取编码后的文件名
     *
     * @param request
     * @param fileName
     * @return
     */
    public static String getEncodeName(HttpServletRequest request, String fileName) {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Postman")) {
            try {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {// 非IE浏览器的处理:
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        return fileName;
    }

    /**
     * 实时查询在职员工
     *
     * @param userId
     * @return
     */
    public List<StaffBaseInfoDTO> queryRealTimeManageStaffs(Long userId) {
        List<StaffBaseInfoDTO> managerStaffs = ehrRpcService.queryManageStaffs(userId);
        if (PublicUtil.isEmpty(managerStaffs)) {
            managerStaffs = new ArrayList<>();
        }
        List<StaffBaseInfoDTO> selectVOS = managerStaffs.stream()
                .filter(staff -> (! staff.getId().equals(userId)))
                .collect(Collectors.toList());
        return selectVOS;
    }

    /**
     * 查询离职、在职员工
     *
     * @param userId
     * @param yearMonth
     * @return
     */
    public List<StaffBaseInfoDTO> queryManageStaffs(Long userId, YearMonth yearMonth) {
        List<StaffBaseInfoDTO> managerStaffs = ehrRpcService.queryManageStaffs(userId);
        if (PublicUtil.isEmpty(managerStaffs)) {
            managerStaffs = new ArrayList<>();
        }
        LocalDate startDate = LocalDate.of(yearMonth.getYear(), yearMonth.getMonth(), 1);
        LocalDate endDate = startDate.with(TemporalAdjusters.lastDayOfMonth());
        LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
        Date firstDayOfMonth = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant());
        Date endDayOfMonth = Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant());
        List<StaffBaseInfoDTO> leaveManagerStaffs = ehrRpcService.queryLeaveManageStaffs(userId, firstDayOfMonth, endDayOfMonth);
        if (PublicUtil.isNotEmpty(leaveManagerStaffs)) {
            managerStaffs.addAll(leaveManagerStaffs);
        }
        List<StaffBaseInfoDTO> selectVOS = managerStaffs.stream()
                .filter(staff -> (! staff.getId().equals(userId)))
                .collect(Collectors.toList());
        return selectVOS;
    }

    /**
     * 查询离职、在职员工id
     *
     * @param userId
     * @param yearMonth
     * @return
     */
    public List<Long> queryManageStaffIds(Long userId, YearMonth yearMonth) {
        List<StaffBaseInfoDTO> staffBaseInfoDTOS = this.queryManageStaffs(userId, yearMonth);
        if (PublicUtil.isNotEmpty(staffBaseInfoDTOS)) {
            return staffBaseInfoDTOS.stream().map(StaffBaseInfoDTO::getId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 查询离职员工id
     *
     * @param shopId
     * @param yearMonth
     * @return
     */
    public List<Long> queryShopLeaveStaffIds(Long shopId, YearMonth yearMonth) {
        List<Long> shopIds = new ArrayList<Long>(){{add(shopId);}};

        LocalDate startDate = LocalDate.of(yearMonth.getYear(), yearMonth.getMonth(), 1);
        LocalDate endDate = startDate.with(TemporalAdjusters.lastDayOfMonth());
        LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
        Date firstDayOfMonth = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant());
        Date endDayOfMonth = Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant());

        List<StaffBaseInfoDTO> staffBaseInfoDTOS = ehrRpcService.queryShopLeaveStaff(shopIds, firstDayOfMonth, endDayOfMonth);
        if (PublicUtil.isNotEmpty(staffBaseInfoDTOS)) {
            return staffBaseInfoDTOS.stream().map(StaffBaseInfoDTO::getId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 查询具体指标值
     * @param indicatorCode
     * @param indicatorUserValue
     * @return
     */
    public BigDecimal queryIndicatorValue(String indicatorCode, IndicatorUserValue indicatorUserValue) {
        if (PublicUtil.isEmpty(indicatorUserValue)) {
            return BigDecimal.ZERO;
        }
        BigDecimal value = BigDecimal.ZERO;
        //条件计算类型 是车系id:销售台数
        if (IndicatorValueTypeEnum.CONDITION.equals(indicatorUserValue.getValueType())) {
            return value;
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(indicatorUserValue.getIndicatorValue());
            value = Optional.ofNullable(jsonObject.getBigDecimal(indicatorCode)).orElse(BigDecimal.ZERO);
        } catch (Exception e) {
            log.error("[{}]指标值转化失败", indicatorCode, e);
        }
        return value;
    }

    /**
     * 查询具体指标值
     * @param indicatorCode
     * @param indicatorValue
     * @return
     */
    public BigDecimal queryEvalIndicatorValue(String indicatorCode, EvalIndicatorValue indicatorValue) {
        if (PublicUtil.isEmpty(indicatorValue)) {
            return BigDecimal.ZERO;
        }
        BigDecimal value = BigDecimal.ZERO;
        try {
            value = Optional.ofNullable(indicatorValue.getIndicatorValue()).orElse(BigDecimal.ZERO);
        } catch (Exception e) {
            log.error("[{}]指标值转化失败", indicatorCode, e);
        }
        return value;
    }

    /**
     * 查询具体指标值
     * @param indicatorCode
     * @param indicatorUserValue
     * @return
     */
    public BigDecimal queryIndicatorValueVO(String indicatorCode, IndicatorUserValueVO indicatorUserValue) {
        BigDecimal value = BigDecimal.ZERO;
        //条件计算类型 是车系id:销售台数
        if (IndicatorValueTypeEnum.CONDITION.equals(indicatorUserValue.getValueType())) {
            return value;
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(indicatorUserValue.getIndicatorValue());
            value = Optional.ofNullable(jsonObject.getBigDecimal(indicatorCode)).orElse(BigDecimal.ZERO);
            if (IndicatorValueTypeEnum.RATIO.equals(indicatorUserValue.getValueType())) {
                value = value.multiply(Constant.ONE_HUNDRED);
            }
        } catch (Exception e) {
            log.error("[{}]指标值转化失败", indicatorCode, e);
        }
        return value;
    }

    /**
     * 查询具体指标值
     * @param indicatorCode
     * @param indicatorUserValue
     * @return
     */
    public BigDecimal queryEvalIndicatorValueVO(String indicatorCode, EvalIndicatorValue indicatorUserValue) {
        BigDecimal value = BigDecimal.ZERO;
        //条件计算类型 是车系id:销售台数
        try {
            value = Optional.ofNullable(indicatorUserValue.getIndicatorValue()).orElse(BigDecimal.ZERO);
            if (DataTypeEnum.RATIO.equals(indicatorUserValue.getDataType())) {
                value = value.multiply(Constant.ONE_HUNDRED);
            }
        } catch (Exception e) {
            log.error("[{}]指标值转化失败", indicatorCode, e);
        }
        return value;
    }

    /**
     * 是否拥有管理角色
     *
     * @return
     */
    public Boolean hasManagerRole(List<String> roleCodes) {
        if (PublicUtil.isEmpty(roleCodes)) {
            return Boolean.FALSE;
        }
        HashSet<String> roleCodeSet = new HashSet<>(roleCodes);
        return Arrays.stream(RoleManagerEnum.values())
                .anyMatch(roleManagerEnum -> roleCodeSet.contains(roleManagerEnum.getCode()));
    }

    /**
     * 获取重名的草稿
     *
     * @param name
     * @param type
     * @param excludeDraftId
     * @return
     */
    public List<SettingDraft> getEditDraftByName(String name, SettingDraftTypeEnum type, Long excludeDraftId) {
        List<SettingDraft> settingDrafts = settingDraftService.list(Wrappers.<SettingDraft>lambdaQuery()
                .eq(SettingDraft::getName, name)
                .eq(SettingDraft::getType, type)
                .ne(SettingDraft::getStatus, SettingDraftStatusEnum.RELEASE_APPROVAL_AGREE)
                .ne(PublicUtil.isNotEmpty(excludeDraftId), SettingDraft::getId, excludeDraftId)
                .eq(SettingDraft::getYn, Boolean.TRUE)
        );
        return settingDrafts;
    }

    /**
     * 设置排名序号
     *
     * @return
     */
    public void calcRank(List<EvalGroupRewardRankLog> rankLogs) {
        int rank = 1;
        BigDecimal lastIndicatorValue = null;
        for (EvalGroupRewardRankLog rankLog : rankLogs) {
            //初始化
            if (PublicUtil.isEmpty(lastIndicatorValue)) {
                rankLog.setRank(rank);
                lastIndicatorValue = rankLog.getReachValue();
                continue;
            }
            if (lastIndicatorValue.compareTo(rankLog.getReachValue()) != 0) {
                rank++;
            }
            rankLog.setRank(rank);
            lastIndicatorValue = rankLog.getReachValue();
        }
    }

}