package thyyxxk.webserver.service.medicalinsurance.costcontrol;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.medicalinsurance.costcontrol.YbStatDao;
import thyyxxk.webserver.entity.HeadInfo;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.medicalinsurance.setlinfo.SiSetlinfo;
import thyyxxk.webserver.entity.medicalinsurance.costcontrol.TreeNodesResult;
import thyyxxk.webserver.entity.medicalinsurance.costcontrol.YbStatDto;
import thyyxxk.webserver.entity.medicalinsurance.costcontrol.YbStatResult;
import thyyxxk.webserver.service.hutoolcache.RegionCache;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.DecimalUtil;
import thyyxxk.webserver.utils.ExcelUtil;
import thyyxxk.webserver.utils.FilterUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName YbStatService
 * @Description 医保报表统计
 * @Author hsh
 * @Date 2022/6/17 9:01
 **/
@Service
public class YbStatService {

    private final YbStatDao dao;

    private final RegionCache regionCache;

    @Autowired
    public YbStatService(YbStatDao dao, RegionCache regionCache) {
        this.dao = dao;
        this.regionCache = regionCache;
    }

    public ResultVo<List<YbStatResult>> selectYbStatInfo(YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String insurType = dto.getInsurType();
        String setlType = dto.getSetlType();
        String d1 = beginTime.replace(" ", "").replace("-", "").replace(":", "");
        String d2 = endTime.replace(" ", "").replace("-", "").replace(":", "");

        // 统筹区域
        List<String> insuplcAdmdvs = new ArrayList<>();
        // 险种类型
        List<String> insurtype = new ArrayList<>();
        // 医疗类别
        List<String> med_type = new ArrayList<>();
        // 返回结果
        List<YbStatResult> ybStatResult = new ArrayList<>();

        if ("21".equals(setlType)) {
            // 住院
            if ("43010031001".equals(insurType) || "99".equals(insurType)) {
                // 长沙市城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙市城职普通住院");
                    result.setInsurType("99".equals(insurType) ? "43010031001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43010039001".equals(insurType) || "99".equals(insurType)) {
                // 长沙市城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙市城居普通住院");
                    result.setInsurType("99".equals(insurType) ? "43010039001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43010034001".equals(insurType) || "99".equals(insurType)) {
                // 长沙市离休
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙市离休");
                    result.setInsurType("99".equals(insurType) ? "43010034001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43010051052".equals(insurType) || "99".equals(insurType)) {
                // 长沙市生育
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙市生育");
                    result.setInsurType("99".equals(insurType) ? "43010051052" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43012131001".equals(insurType) || "99".equals(insurType)) {
                // 长沙县城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430121");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙县城职普通住院");
                    result.setInsurType("99".equals(insurType) ? "43012131001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43012139001".equals(insurType) || "99".equals(insurType)) {
                // 长沙县城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430121");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙县城居普通住院");
                    result.setInsurType("99".equals(insurType) ? "43012139001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43012134001".equals(insurType) || "99".equals(insurType)) {
                // 长沙县离休
                insuplcAdmdvs.add("430121");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙县离休");
                    result.setInsurType("99".equals(insurType) ? "43012134001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43012151052".equals(insurType) || "99".equals(insurType)) {
                // 长沙县生育
                insuplcAdmdvs.add("430121");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("长沙县生育");
                    result.setInsurType("99".equals(insurType) ? "43012151052" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018131001".equals(insurType) || "99".equals(insurType)) {
                // 浏阳县城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430181");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("浏阳县城职普通住院");
                    result.setInsurType("99".equals(insurType) ? "43018131001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018139001".equals(insurType) || "99".equals(insurType)) {
                // 浏阳县城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430181");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("浏阳县城居普通住院");
                    result.setInsurType("99".equals(insurType) ? "43018139001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018134001".equals(insurType) || "99".equals(insurType)) {
                // 浏阳县离休
                insuplcAdmdvs.add("430181");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("浏阳县离休");
                    result.setInsurType("99".equals(insurType) ? "43018134001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018151052".equals(insurType) || "99".equals(insurType)) {
                // 浏阳县生育
                insuplcAdmdvs.add("430181");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("浏阳县生育");
                    result.setInsurType("99".equals(insurType) ? "43018151052" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018231001".equals(insurType) || "99".equals(insurType)) {
                // 宁乡市城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430182");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("宁乡市城职普通住院");
                    result.setInsurType("99".equals(insurType) ? "43018231001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43018239001".equals(insurType) || "99".equals(insurType)) {
                // 宁乡市城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430182");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("宁乡市城居普通住院");
                    result.setInsurType("99".equals(insurType) ? "43018239001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43990031001".equals(insurType) || "99".equals(insurType)) {
                // 湖南省城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("439900");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("湖南省城职普通住院");
                    result.setInsurType("99".equals(insurType) ? "43990031001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43990034001".equals(insurType) || "99".equals(insurType)) {
                // 湖南省离休
                insuplcAdmdvs.add("439900");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("湖南省离休");
                    result.setInsurType("99".equals(insurType) ? "43990034001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43990051052".equals(insurType) || "99".equals(insurType)) {
                // 湖南省生育
                insuplcAdmdvs.add("439900");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("湖南省生育");
                    result.setInsurType("99".equals(insurType) ? "43990051052" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43990001".equals(insurType) || "99".equals(insurType)) {
                // 省内异地(包含外伤住院)
                YbStatResult result = dao.selectYbStatInfoInProvinceOtherCities(beginTime, endTime, setlType);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("省内异地");
                    result.setInsurType("99".equals(insurType) ? "43990001" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("43990002".equals(insurType) || "99".equals(insurType)) {
                // 省外异地(包含外伤住院)
                YbStatResult result = dao.selectYbStatInfoInOutProvinceCities(beginTime, endTime, setlType);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("省外异地");
                    result.setInsurType("99".equals(insurType) ? "43990002" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("4301002102".equals(insurType) || "99".equals(insurType)) {
                // 市单病种
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insuplcAdmdvs.add("430121");
                insuplcAdmdvs.add("430181");
                med_type.add("2102");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("市单病种");
                    result.setInsurType("99".equals(insurType) ? "4301002102" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("4399002102".equals(insurType) || "99".equals(insurType)) {
                // 省城职单病种
                insuplcAdmdvs.add("439900");
                med_type.add("2102");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("省单病种");
                    result.setInsurType("99".equals(insurType) ? "4399002102" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("4399012102".equals(insurType) || "99".equals(insurType)) {
                // 省内异地单病种
                YbStatResult result = dao.selectYbStatInfoInProvinceOtherCitiesSingleDisease(beginTime, endTime, setlType);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("省内异地单病种");
                    result.setInsurType("99".equals(insurType) ? "4399012102" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();

            if ("431321410".equals(insurType) || "99".equals(insurType)) {
                // 住院所有工伤病人
                YbStatResult result = dao.selectYbStatInfoIninjury(d1, d2, setlType);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("住院工伤");
                    result.setInsurType("99".equals(insurType) ? "431321410" : insurType);
                    ybStatResult.add(result);
                }
            }

        } else {
            // 门诊
            if ("11".equals(insurType) || "99".equals(insurType)) {
                // 普通门诊
                med_type.add("11");
                med_type.add("9903");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("普通门诊");
                    result.setInsurType("99".equals(insurType) ? "11" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("14".equals(insurType) || "99".equals(insurType)) {
                // 门诊慢特病
                med_type.add("14");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("特殊门诊");
                    result.setInsurType("99".equals(insurType) ? "14" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("51".equals(insurType) || "99".equals(insurType)) {
                // 生育门诊
                med_type.add("51");
                YbStatResult result = dao.selectYbStatInfo(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("生育门诊");
                    result.setInsurType("99".equals(insurType) ? "51" : insurType);
                    ybStatResult.add(result);
                }
            }

            insuplcAdmdvs.clear();
            insurtype.clear();
            med_type.clear();
            if ("98".equals(insurType) || "99".equals(insurType)) {
                // 工伤门诊
                YbStatResult result = dao.selectYbStatInfoIninjury(d1, d2, setlType);
                if (!ObjectUtils.isEmpty(result) && result.getPsnCount() > 0) {
                    result.setInsurName("门诊工伤");
                    result.setInsurType("99".equals(insurType) ? "98" : insurType);
                    ybStatResult.add(result);
                }
            }

        }

        if (ybStatResult.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }

        return ResultVoUtil.success(ybStatResult);
    }

    /**
     *@Author hsh
     *@Description // 计算同比/环比
     *@Date 2022/6/29 16:01
     *@Param [dto]
     *@Return thyyxxk.webserver.entity.ResultVo<java.util.List < java.util.Map < java.lang.String, java.lang.Object>>>
     **/
    public ResultVo<List<Map<String, Object>>> selectYbStatRatio(YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String setlType = dto.getSetlType();
        String selectType = dto.getSelectType();

        String year = beginTime.substring(0, 4);
        int lastYear = Integer.parseInt(year) - 1;
        // 开始月份
        String mouthS = beginTime.startsWith("10", 5) ? "10" : beginTime.substring(5, 7).replace("0", "");
        int m = Integer.parseInt(mouthS);
        // 结束月份
        String mouthE = endTime.startsWith("10", 5) ? "10" : endTime.substring(5, 7).replace("0", "");
        // 数据月份
        int le = Integer.parseInt(mouthE) - Integer.parseInt(mouthS);

        List<Map<String, Object>> ybStatRatio = new ArrayList<>();

        // 查询本年数据
        List<YbStatResult> result1 = dao.selectYbStatRatio(beginTime, endTime, setlType);
        Map<String, YbStatResult> mapYf1 = new HashMap<>();
        for (YbStatResult r : result1) {
            mapYf1.put(r.getYf(), r);
        }

        if ("second".equals(selectType)) {
            // 查询同比
            // 查询上年数据
            String beginTimeLast = DateUtil.getLastYearDate(beginTime, null);
            String endTimeLast = DateUtil.getLastYearDate(endTime, null);
            List<YbStatResult> result2 = dao.selectYbStatRatio(beginTimeLast, endTimeLast, setlType);
            Map<String, YbStatResult> mapYf2 = new HashMap<>();
            for (YbStatResult r : result2) {
                mapYf2.put(r.getYf(), r);
            }

            for (int i = m; i <= m + le; i++) {
                Map<String, Object> result = new HashMap<>();
                String yf1 = "";
                String yf2 = "";
                String yf3 = calCNMonth(i);
                result.put("month", yf3);
                if (i < 10) {
                    yf1 = year + "-0" + i;
                    yf2 = lastYear + "-0" + i;
                } else {
                    yf1 = year + "-" + i;
                    yf2 = lastYear + "-" + i;
                }
                YbStatResult r1 = mapYf1.get(yf1);
                YbStatResult r2 = mapYf2.get(yf2);

                if (!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
                    result.put("zfy_jn", r1.getTotalFee());
                    result.put("zjj_jn", r1.getAllFunds());
                    result.put("ypf_jn", r1.getDrugFee());
                    result.put("clf_jn", r1.getMatFee());

                    if (!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0) {
                        result.put("zfy_qn", r2.getTotalFee());
                        result.put("zjj_qn", r2.getAllFunds());
                        result.put("ypf_qn", r2.getDrugFee());
                        result.put("clf_qn", r2.getMatFee());

                        // 都有值的时候计算同比增长率（同比增长速度=（本期发展水平-同期水平）/同期发展水平×100%）
                        if (Double.parseDouble(r2.getTotalFee()) > 0) {
                            String zfyTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
                            result.put("zfy_tb", zfyTb);
                        } else {
                            result.put("zfy_tb", "");
                        }

                        if (Double.parseDouble(r2.getAllFunds()) > 0) {
                            String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
                            result.put("zjj_tb", zjjTb);
                        } else {
                            result.put("zjj_tb", "");
                        }

                        if (Double.parseDouble(r2.getDrugFee()) > 0) {
                            String ypfTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
                            result.put("ypf_tb", ypfTb);
                        } else {
                            result.put("ypf_tb", "");
                        }

                        if (Double.parseDouble(r2.getMatFee()) > 0) {
                            String clfTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
                            result.put("clf_tb", clfTb);
                        } else {
                            result.put("clf_tb", "");
                        }

                    } else {
                        result.put("zfy_qn", "");
                        result.put("zjj_qn", "");
                        result.put("ypf_qn", "");
                        result.put("clf_qn", "");
                        result.put("zfy_tb", "");
                        result.put("zjj_tb", "");
                        result.put("ypf_tb", "");
                        result.put("clf_tb", "");
                    }
                } else {
                    if (!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0) {
                        result.put("zfy_qn", r2.getTotalFee());
                        result.put("zjj_qn", r2.getAllFunds());
                        result.put("ypf_qn", r2.getDrugFee());
                        result.put("clf_qn", r2.getMatFee());
                        result.put("zfy_jn", "");
                        result.put("zjj_jn", "");
                        result.put("ypf_jn", "");
                        result.put("clf_jn", "");
                        result.put("zfy_tb", "");
                        result.put("zjj_tb", "");
                        result.put("ypf_tb", "");
                        result.put("clf_tb", "");
                    }
                }
                ybStatRatio.add(result);
            }

        } else {
            // 查询环比
            for (int i = m; i <= m + le; i++) {
                Map<String, Object> result = new HashMap<>();
                String yf1 = "";
                // 上一个月
                String yf2 = "";
                String yf3 = calCNMonth(i);
                result.put("month", yf3);
                int s = i - 1;
                if (i < 10) {
                    yf1 = year + "-0" + i;
                } else {
                    yf1 = year + "-" + i;
                }
                if (s < 10) {
                    yf2 = year + "-0" + s;
                } else {
                    yf2 = year + "-" + s;
                }

                YbStatResult r1 = mapYf1.get(yf1);
                if (i == m) {
                    if (!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
                        result.put("zfy", r1.getTotalFee());
                        result.put("zjj", r1.getAllFunds());
                        result.put("ypf", r1.getDrugFee());
                        result.put("clf", r1.getMatFee());
                        result.put("zfy_hb", "");
                        result.put("zjj_hb", "");
                        result.put("ypf_hb", "");
                        result.put("clf_hb", "");
                    } else {
                        result.put("zfy", "0");
                        result.put("zjj", "0");
                        result.put("ypf", "0");
                        result.put("clf", "0");
                        result.put("zfy_hb", "");
                        result.put("zjj_hb", "");
                        result.put("ypf_hb", "");
                        result.put("clf_hb", "");
                    }
                } else {
                    YbStatResult r2 = mapYf1.get(yf2);
                    if (!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
                        result.put("zfy", r1.getTotalFee());
                        result.put("zjj", r1.getAllFunds());
                        result.put("ypf", r1.getDrugFee());
                        result.put("clf", r1.getMatFee());
                        // 都有值的时候计算环比增长率（环比增长速度=（本月发展水平-上月发展水平）/上月发展水平×100%）
                        if (Double.parseDouble(r2.getTotalFee()) > 0) {
                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
                            result.put("zfy_hb", hb);
                        } else {
                            result.put("zfy_hb", "");
                        }

                        if (r2.getAllFunds() != null && Double.parseDouble(r2.getAllFunds()) > 0) {
                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
                            result.put("zjj_hb", hb);
                        } else {
                            result.put("zjj_hb", "");
                        }

                        if (r2.getDrugFee() != null && Double.parseDouble(r2.getDrugFee()) > 0) {
                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
                            result.put("ypf_hb", hb);
                        } else {
                            result.put("ypf_hb", "");
                        }

                        if (r2.getMatFee() != null && Double.parseDouble(r2.getMatFee()) > 0) {
                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
                            result.put("clf_hb", hb);
                        } else {
                            result.put("clf_hb", "");
                        }
                    }

                }
                ybStatRatio.add(result);
            }

        }

        return ResultVoUtil.success(ybStatRatio);
    }

    /**
     *@Author hsh
     *@Description // 根据数字转换中文月份
     *@Date 2022/6/29 16:55
     *@Param [i]
     *@Return java.lang.String
     **/
    private String calCNMonth(int i) {
        String yf;
        switch (i) {
            case 1:
                yf = "一月";
                break;
            case 2:
                yf = "二月";
                break;
            case 3:
                yf = "三月";
                break;
            case 4:
                yf = "四月";
                break;
            case 5:
                yf = "五月";
                break;
            case 6:
                yf = "六月";
                break;
            case 7:
                yf = "七月";
                break;
            case 8:
                yf = "八月";
                break;
            case 9:
                yf = "九月";
                break;
            case 10:
                yf = "十月";
                break;
            case 11:
                yf = "十一月";
                break;
            case 12:
                yf = "十二月";
                break;
            default:
                yf = "";
        }
        return yf;
    }

    public ResultVo<String> exportYbStatRatioExcel(HttpServletResponse response, YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String setlType = dto.getSetlType();
        String selectType = dto.getSelectType();
        ResultVo<List<Map<String, Object>>> rs = selectYbStatRatio(dto);
        List<Map<String, Object>> list = rs.getData();

        if (null == list) {
            String log = "导出没有数据";
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, log);
        }

        // 计算合计
        // 查询今年数据
        YbStatResult r1 = dao.selectYbStatRatioTotal(beginTime, endTime, setlType);
        // 查询上年数据
        String beginTimeLast = DateUtil.getLastYearDate(beginTime, null);
        String endTimeLast = DateUtil.getLastYearDate(endTime, null);
        YbStatResult r2 = dao.selectYbStatRatioTotal(beginTimeLast, endTimeLast, setlType);

        // 计算合计
        Map<String, Object> result = calTotalInfo(r1, r2, selectType);
        list.add(result);

        // 导出标题
        String exportName = dto.getExportName();

        // 组装表头
        List<HeadInfo> headInfoList = calHeadList(selectType);

        // 导出
        ExcelUtil.exportExcelReport(response, list, headInfoList, exportName);

        String log = "导出成功";
        return ResultVoUtil.success(log);
    }

    private List<HeadInfo> calHeadList(String selectType) {
        List<HeadInfo> headInfoList = new ArrayList<>();
        if ("second".equals(selectType)) {
            HeadInfo headInfo = new HeadInfo();
            headInfo.setDisplay("月份");
            headInfo.setName("month");
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("总费用");
            headInfo.setName("zfy");

            List<HeadInfo> headInfoList1 = new ArrayList<>();
            HeadInfo headInfo1 = new HeadInfo();
            headInfo1.setDisplay("今年");
            headInfo1.setName("zfy_jn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("去年");
            headInfo1.setName("zfy_qn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("同比");
            headInfo1.setName("zfy_tb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("全部基金");
            headInfo.setName("zjj");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("今年");
            headInfo1.setName("zjj_jn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("去年");
            headInfo1.setName("zjj_qn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("同比");
            headInfo1.setName("zjj_tb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("药品费用");
            headInfo.setName("ypf");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("今年");
            headInfo1.setName("ypf_jn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("去年");
            headInfo1.setName("ypf_qn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("同比");
            headInfo1.setName("ypf_tb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("耗材费用");
            headInfo.setName("clf");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("今年");
            headInfo1.setName("clf_jn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("去年");
            headInfo1.setName("clf_qn");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("同比");
            headInfo1.setName("clf_tb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);
        } else {
            HeadInfo headInfo = new HeadInfo();
            headInfo.setDisplay("月份");
            headInfo.setName("month");
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("总费用");
            headInfo.setName("zfys");

            List<HeadInfo> headInfoList1 = new ArrayList<>();
            HeadInfo headInfo1 = new HeadInfo();
            headInfo1.setDisplay("费用");
            headInfo1.setName("zfy");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("环比");
            headInfo1.setName("zfy_hb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("全部基金");
            headInfo.setName("zjjs");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("费用");
            headInfo1.setName("zjj");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("环比");
            headInfo1.setName("zjj_hb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("药品费用");
            headInfo.setName("ypfs");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("费用");
            headInfo1.setName("ypf");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("环比");
            headInfo1.setName("ypf_hb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);

            headInfo = new HeadInfo();
            headInfo.setDisplay("耗材费用");
            headInfo.setName("clfs");

            headInfoList1 = new ArrayList<>();
            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("费用");
            headInfo1.setName("clf");
            headInfoList1.add(headInfo1);

            headInfo1 = new HeadInfo();
            headInfo1.setDisplay("环比");
            headInfo1.setName("clf_hb");
            headInfoList1.add(headInfo1);

            headInfo.setColumns(headInfoList1);
            headInfoList.add(headInfo);
        }
        return headInfoList;
    }

    private Map<String, Object> calTotalInfo(YbStatResult r1, YbStatResult r2, String selectType) {
        Map<String, Object> result = new HashMap<>();
        if ("second".equals(selectType)) {
            if (!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
                result.put("zfy_jn", r1.getTotalFee());
                result.put("zjj_jn", r1.getAllFunds());
                result.put("ypf_jn", r1.getDrugFee());
                result.put("clf_jn", r1.getMatFee());

                if (!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0) {
                    result.put("zfy_qn", r2.getTotalFee());
                    result.put("zjj_qn", r2.getAllFunds());
                    result.put("ypf_qn", r2.getDrugFee());
                    result.put("clf_qn", r2.getMatFee());

                    // 都有值的时候计算同比增长率（同比增长速度=（本期发展水平-同期水平）/同期发展水平×100%）
                    String zfyTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
                    result.put("zfy_tb", zfyTb);

                    if (Double.parseDouble(r2.getAllFunds()) > 0) {
                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
                        result.put("zjj_tb", zjjTb);
                    } else {
                        result.put("zjj_tb", "");
                    }

                    if (Double.parseDouble(r2.getDrugFee()) > 0) {
                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
                        result.put("ypf_tb", zjjTb);
                    } else {
                        result.put("ypf_tb", "");
                    }

                    if (Double.parseDouble(r2.getMatFee()) > 0) {
                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
                        result.put("clf_tb", zjjTb);
                    } else {
                        result.put("clf_tb", "");
                    }

                } else {
                    result.put("zfy_qn", "");
                    result.put("zjj_qn", "");
                    result.put("ypf_qn", "");
                    result.put("clf_qn", "");
                    result.put("zfy_tb", "");
                    result.put("zjj_tb", "");
                    result.put("ypf_tb", "");
                    result.put("clf_tb", "");
                }
            } else {
                if (!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0) {
                    result.put("zfy_qn", r2.getTotalFee());
                    result.put("zjj_qn", r2.getAllFunds());
                    result.put("ypf_qn", r2.getDrugFee());
                    result.put("clf_qn", r2.getMatFee());
                    result.put("zfy_jn", "");
                    result.put("zjj_jn", "");
                    result.put("ypf_jn", "");
                    result.put("clf_jn", "");
                    result.put("zfy_tb", "");
                    result.put("zjj_tb", "");
                    result.put("ypf_tb", "");
                    result.put("clf_tb", "");
                }
            }
        } else {
            if (!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
                result.put("zfy", r1.getTotalFee());
                result.put("zjj", r1.getAllFunds());
                result.put("ypf", r1.getDrugFee());
                result.put("clf", r1.getMatFee());
                result.put("zfy_tb", "");
                result.put("zjj_tb", "");
                result.put("ypf_tb", "");
                result.put("clf_tb", "");
            } else {
                result.put("zfy", 0);
                result.put("zjj", 0);
                result.put("ypf", 0);
                result.put("clf", 0);
                result.put("zfy_tb", "");
                result.put("zjj_tb", "");
                result.put("ypf_tb", "");
                result.put("clf_tb", "");
            }
        }
        result.put("month", "合计");
        return result;
    }

    /**
     *@Author hsh
     *@Description // 查询柱状图医保统计数据
     *@Date 2022/7/5 11:26
     *@Param [dto]
     *@Return thyyxxk.webserver.entity.ResultVo<java.util.List < java.util.Map < java.lang.String, java.lang.Object>>>
     **/
    public ResultVo<List<Map<String, Object>>> selectYbChart(YbStatDto dto) {
        // 按照同比的数据返回去渲染图形数据
        dto.setSelectType("second");
        ResultVo<List<Map<String, Object>>> rs = selectYbStatRatio(dto);
        List<Map<String, Object>> list = rs.getData();
        if (null == list) {
            String log = "查询没有数据";
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, log);
        }
        return ResultVoUtil.success(list);
    }

    /**
     *@Author hsh
     *@Description // 查询医保明细数据
     *@Date 2022/7/5 11:27
     *@Param [dto]
     *@Return thyyxxk.webserver.entity.ResultVo<java.util.List < thyyxxk.webserver.entity.medicalinsurance.setlinfo.SiSetlinfo>>
     **/
    public ResultVo<List<SiSetlinfo>> selectYbStatDetail(YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String insurType = dto.getInsurType();
        String setlType = dto.getSetlType();

        // 统筹区域
        List<String> insuplcAdmdvs = new ArrayList<>();
        // 险种类型
        List<String> insurtype = new ArrayList<>();
        // 医疗类别
        List<String> med_type = new ArrayList<>();
        // 返回结果
        List<SiSetlinfo> siSetlInfoList = new ArrayList<>();
        String d1 = beginTime.replace(" ", "").replace("-", "").replace(":", "");
        String d2 = endTime.replace(" ", "").replace("-", "").replace(":", "");
        if ("21".equals(setlType)) {
            // 住院
            if ("43010031001".equals(insurType)) {
                // 长沙市城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43010039001".equals(insurType)) {
                // 长沙市城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43010034001".equals(insurType)) {
                // 长沙市离休
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43010051052".equals(insurType)) {
                // 长沙市生育
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43012131001".equals(insurType)) {
                // 长沙县城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430121");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43012139001".equals(insurType)) {
                // 长沙县城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430121");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43012134001".equals(insurType)) {
                // 长沙县离休
                insuplcAdmdvs.add("430121");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43012151052".equals(insurType)) {
                // 长沙县生育
                insuplcAdmdvs.add("430121");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018131001".equals(insurType)) {
                // 浏阳县城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430181");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018139001".equals(insurType)) {
                // 浏阳县城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430181");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018134001".equals(insurType)) {
                // 浏阳县离休
                insuplcAdmdvs.add("430181");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018151052".equals(insurType)) {
                // 浏阳县生育
                insuplcAdmdvs.add("430181");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018231001".equals(insurType)) {
                // 宁乡市城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("430182");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43018239001".equals(insurType)) {
                // 宁乡市城居普通住院(包含外伤住院)
                insuplcAdmdvs.add("430182");
                insurtype.add("390");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43990031001".equals(insurType)) {
                // 湖南省城职普通住院(包含外伤住院)
                insuplcAdmdvs.add("439900");
                insurtype.add("310");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43990034001".equals(insurType)) {
                // 湖南省离休
                insuplcAdmdvs.add("439900");
                insurtype.add("340");
                med_type.add("2101");
                med_type.add("22");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43990051052".equals(insurType)) {
                // 湖南省生育
                insuplcAdmdvs.add("439900");
                med_type.add("52");
                med_type.add("2106");
                med_type.add("2107");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("43990001".equals(insurType)) {
                // 省内异地(包含外伤住院)
                siSetlInfoList = dao.selectSiSetlInfoListInProvinceOtherCities(beginTime, endTime, setlType);
            } else if ("43990002".equals(insurType)) {
                // 省外异地(包含外伤住院)
                siSetlInfoList = dao.selectSiSetlInfoListInOutProvinceCities(beginTime, endTime, setlType);
            } else if ("4301002102".equals(insurType)) {
                // 市单病种
                insuplcAdmdvs.add("430102");
                insuplcAdmdvs.add("430103");
                insuplcAdmdvs.add("430104");
                insuplcAdmdvs.add("430105");
                insuplcAdmdvs.add("430111");
                insuplcAdmdvs.add("430112");
                insuplcAdmdvs.add("430140");
                insuplcAdmdvs.add("430199");
                insuplcAdmdvs.add("430121");
                insuplcAdmdvs.add("430181");
                med_type.add("2102");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("4399002102".equals(insurType)) {
                // 省城职单病种
                insuplcAdmdvs.add("439900");
                med_type.add("2102");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("4399012102".equals(insurType)) {
                // 省内异地单病种
                siSetlInfoList = dao.selectSiSetlInfoListInProvinceOtherCitiesSingleDisease(beginTime, endTime, setlType);
            } else if ("431321410".equals(insurType)) {
                // 住院工伤
                siSetlInfoList = dao.selectInjurySetlInfoList(d1, d2, setlType);
            }

        } else {
            // 门诊
            if ("11".equals(insurType)) {
                // 普通门诊
                med_type.add("11");
                med_type.add("9903");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("14".equals(insurType)) {
                // 门诊慢特病
                med_type.add("14");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("51".equals(insurType)) {
                // 生育门诊
                med_type.add("51");
                siSetlInfoList = dao.selectSiSetlInfoList(beginTime, endTime, setlType, insuplcAdmdvs, insurtype, med_type);
            } else if ("98".equals(insurType)) {
                siSetlInfoList = dao.selectInjurySetlInfoList(d1, d2, setlType);
            }

        }

        if (null == siSetlInfoList || siSetlInfoList.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }

        siSetlInfoList.forEach(item -> {
            // 工伤不计算其他支出
            if (!("431321410".equals(insurType) || "98".equals(insurType))) {
                String othpay = DecimalUtil.minusLink(String.valueOf(item.getFundPaySumamt()), String.valueOf(item.getHifpPay()), String.valueOf(item.getHifmiPay()), String.valueOf(item.getCvlservPay()));
                item.setOthPay("".equals(othpay) ? 0d : Double.parseDouble(othpay));
            }
            item.setInsuplcAdmdvsName(regionCache.get(item.getInsuplcAdmdvs()));
            FilterUtil.filterCodeToName(item);
        });

        return ResultVoUtil.success(siSetlInfoList);
    }

    public ResultVo<List<Map<String, Object>>> selectBarChangeData(YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        // 不限制查询险种类型
        String setlType = dto.getSetlType();

        List<Map<String, Object>> list = dao.selectBarChangeData(beginTime, endTime, setlType);

        if (null == list || list.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }

        Map<String, List<Map<String, Object>>> map1 = list.stream().collect(Collectors.groupingBy(f -> String.valueOf(f.get("yf")), Collectors.toList()));
        List<Map<String, Object>> result = new ArrayList<>();
        List<Map<String, Object>> list1 = new ArrayList<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : map1.entrySet()) {
            List<Map<String, Object>> list2 = entry.getValue();
            if (list2 == null && list2.size() < 1) {
                continue;
            }

            if (result != null && result.size() < 1) {
                list1.addAll(list2);
                result.addAll(list2);
            } else {
                List<Map<String, Object>> sl = new ArrayList<>();
                for (Map<String, Object> m1 : list1) {
                    Map<String, Object> m = new HashMap<>();
                    String medinsType1 = m1.get("medins_type") + "";
                    boolean flag = true;
                    for (Map<String, Object> m2 : list2) {
                        String medinsType2 = m2.get("medins_type") + "";
                        if (medinsType1.equals(medinsType2)) {
                            flag = false;
                            m.put("yf", entry.getKey());
                            m.put("medins_type", medinsType1);
                            m.put("psnCount", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("psnCount"))), new BigDecimal(String.valueOf(m1.get("psnCount")))));
                            m.put("inDays", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("inDays"))), new BigDecimal(String.valueOf(m1.get("inDays")))));
                            m.put("totalFee", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("totalFee"))), new BigDecimal(String.valueOf(m1.get("totalFee")))));
                            m.put("fundPooling", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("fundPooling"))), new BigDecimal(String.valueOf(m1.get("fundPooling")))));
                            m.put("bigIllFundPooling", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("bigIllFundPooling"))), new BigDecimal(String.valueOf(m1.get("bigIllFundPooling")))));
                            m.put("civilServiceFund", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("civilServiceFund"))), new BigDecimal(String.valueOf(m1.get("civilServiceFund")))));
                            m.put("otherFunds", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("otherFunds"))), new BigDecimal(String.valueOf(m1.get("otherFunds")))));
                            m.put("allFunds", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("allFunds"))), new BigDecimal(String.valueOf(m1.get("allFunds")))));
                            m.put("drugFee", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("drugFee"))), new BigDecimal(String.valueOf(m1.get("drugFee")))));
                            m.put("matFee", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("matFee"))), new BigDecimal(String.valueOf(m1.get("matFee")))));
                            m.put("otherFunds", DecimalUtil.add(new BigDecimal(String.valueOf(m2.get("otherFunds"))), new BigDecimal(String.valueOf(m1.get("otherFunds")))));
                            break;
                        }
                    }

                    if (flag) {
                        m.put("yf", entry.getKey());
                        m.put("medins_type", medinsType1);
                        m.put("psnCount", m1.get("psnCount"));
                        m.put("inDays", m1.get("inDays"));
                        m.put("totalFee", m1.get("totalFee"));
                        m.put("fundPooling", m1.get("fundPooling"));
                        m.put("bigIllFundPooling", m1.get("bigIllFundPooling"));
                        m.put("civilServiceFund", m1.get("civilServiceFund"));
                        m.put("otherFunds", m1.get("otherFunds"));
                        m.put("allFunds", m1.get("allFunds"));
                        m.put("drugFee", m1.get("drugFee"));
                        m.put("matFee", m1.get("matFee"));
                        m.put("otherFunds", m1.get("otherFunds"));
                    }
                    sl.add(m);
                }

                // 下个月没有上个月的险种的数据，也需要添加到下个月展示
                for (Map<String, Object> m2 : list2) {
                    String medinsType2 = m2.get("medins_type") + "";
                    boolean flag = true;
                    for (Map<String, Object> m1 : sl) {
                        String medinsType1 = m1.get("medins_type") + "";
                        if (medinsType2.equals(medinsType1)) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        sl.add(m2);
                    }
                }
                result.addAll(sl);
                list1.clear();
                list1.addAll(sl);
            }
        }

        result = result.stream().sorted(
                Comparator.nullsLast(Comparator.comparing((Map<String, Object> i) -> i.get("yf").toString()))
        ).collect(Collectors.toList());
        return ResultVoUtil.success(result);
    }


    public ResultVo<TreeNodesResult> selectTreeData(YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String setlType = dto.getSetlType();
        String dept = dto.getDept();
        String doctor = dto.getDoctor();
        String insurType = dto.getInsurType();

        // 存放根节点数据集合
        TreeNodesResult root = dao.getTreeRootResult(beginTime, endTime, setlType);
        // 根节点默认打开
        root.setCollapsed(false);
        // 查询第一子节点数据
        List<TreeNodesResult> secondTreeList = dao.selectTreeSecondData(beginTime, endTime, setlType, insurType);
        // 查询第二子节点数据
        List<TreeNodesResult> thirdTreeList = dao.selectTreeThirdData(beginTime, endTime, setlType, insurType);
        // 查询第三子节点数据
        List<TreeNodesResult> fourthTreeList = dao.selectTreeFourthData(beginTime, endTime, setlType, insurType);

        for (TreeNodesResult treeNodesResult : secondTreeList) {
            if (StringUtil.notBlank(dept)) {
                treeNodesResult.setCollapsed(!treeNodesResult.getName().contains(dept));
            } else {
                // 子节点默认关闭
                treeNodesResult.setCollapsed(true);
            }
        }

        for (TreeNodesResult treeNodesResult : thirdTreeList) {
            if (StringUtil.notBlank(doctor)) {
                treeNodesResult.setCollapsed(!treeNodesResult.getName().contains(doctor));
            } else {
                // 子节点默认关闭
                treeNodesResult.setCollapsed(true);
            }
        }

        Map<String, List<TreeNodesResult>> m11 = fourthTreeList.stream().collect(Collectors.groupingBy(item -> item.getPid() + "_" + item.getUid()));
        for (TreeNodesResult result : thirdTreeList) {
            String id = result.getId();
            String pid = result.getPid();
            List<TreeNodesResult> l1 = m11.get(id + "_" + pid);
            result.setChildren(l1);
        }
        Map<String, List<TreeNodesResult>> m2 = thirdTreeList.stream().collect(Collectors.groupingBy(TreeNodesResult::getPid));
        for (TreeNodesResult result : secondTreeList) {
            String id = result.getId();
            List<TreeNodesResult> l1 = m2.get(id);
            result.setChildren(l1);
        }
        root.setChildren(secondTreeList);
        return ResultVoUtil.success(root);
    }

    public void selectTreeAllData(HttpServletResponse response, YbStatDto dto) {
        String beginTime = dto.getStartTime();
        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
        String setlType = dto.getSetlType();
        String dept = dto.getDept();
        String doctor = dto.getDoctor();
        String insurType = dto.getInsurType();
        List<Map<String, Object>> list = dao.selectTreeAllData(beginTime, endTime, setlType, dept, doctor, insurType);

        if (null == list) {
            return;
        }

        // 导出标题
        String exportName = dto.getExportName();

        // 组装表头
        List<HeadInfo> headInfoList = calTreeRsHeadList();

        // 导出
        ExcelUtil.exportExcelReport(response, list, headInfoList, exportName);
    }

    /**
     * @description: 医生医保病人按参保身份分布人数导出
     * @author: hsh
     * @date: 2022/10/24 15:12
     * @param: []
     * @return: List<HeadInfo>
     **/
    private List<HeadInfo> calTreeRsHeadList() {
        List<HeadInfo> headInfoList = new ArrayList<>();
        HeadInfo headInfo = new HeadInfo();
        headInfo.setDisplay("科室");
        headInfo.setName("deptName");
        headInfoList.add(headInfo);

        headInfo = new HeadInfo();
        headInfo.setDisplay("医生");
        headInfo.setName("doctorName");
        headInfoList.add(headInfo);

        headInfo = new HeadInfo();
        headInfo.setDisplay("险种");
        headInfo.setName("insurName");
        headInfoList.add(headInfo);

        headInfo = new HeadInfo();
        headInfo.setDisplay("人数");
        headInfo.setName("rs");
        headInfoList.add(headInfo);

        return headInfoList;
    }

}
