package com.yihu.wlyy.service.app.statistics;

import com.yihu.wlyy.entity.address.Town;
import com.yihu.wlyy.entity.doctor.team.admin.AdminTeam;
import com.yihu.wlyy.entity.organization.Hospital;
import com.yihu.wlyy.entity.statistics.PopulationBase;
import com.yihu.wlyy.entity.statistics.WlyyQuotaResult;
import com.yihu.wlyy.job.Constant;
import com.yihu.wlyy.repository.address.CityDao;
import com.yihu.wlyy.repository.address.TownDao;
import com.yihu.wlyy.repository.doctor.DoctorAdminTeamDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.organization.HospitalDao;
import com.yihu.wlyy.repository.statistics.PopulationBaseDao;
import com.yihu.wlyy.repository.statistics.WlyyQuotaResultDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.util.DateUtil;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lyr-pc on 2016/10/21.
 */
@Service
public class StatisticsAllService extends BaseService {
    @Autowired
    CityDao cityDao;
    @Autowired
    TownDao townDao;
    @Autowired
    DoctorDao doctorDao;
    @Autowired
    HospitalDao hospitalDao;
    @Autowired
    DoctorAdminTeamDao adminTeamDao;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    PopulationBaseDao peopleNumDao;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private WlyyQuotaResultDao wlyyQuotaResultDao;

    /**
     * 获取时间戳
     *
     * @return
     */
    public String getQuotaTimeStamp() {
        return redisTemplate.opsForValue().get("quota:timeKey");
    }

    /**
     * 获取一级指标达到量
     *
     * @param endDate 截止日期
     * @param area    区域
     * @param index   指标
     * @param level   级别
     * @return
     */
    public long getIndexTotal(String endDate, String area, int level, String index) {
        long total = 0;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        boolean preFlag = false;
        String preDate = endDate;

        if (endDate.compareTo(dateFormat.format(new Date())) >= 0) {
            String val = "";
            try {
                val = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + getQuotaTimeStamp());
            } catch (Exception e) {
                val = "";
            }
            if (!StringUtils.isEmpty(val)) {
                JSONObject valJson = new JSONObject(val);
                if (valJson.has("num")) {
                    total = valJson.getInt("num");
                }
            } else {
                preFlag = true;
                Calendar today = Calendar.getInstance();
                today.add(Calendar.DATE, -1);
                preDate = dateFormat.format(today.getTime());
            }
        } else {
            preFlag = true;
        }
        if (preFlag) {
            // 查询语句
            String sql = " select " +
                    "     ifnull(result,'0') amount" +
                    " from  " +
                    "     wlyy_quota_result " +
                    " where " +
                    "     quato_code = ? " +
                    "   and level1_type = ? and del = '1'" +
                    "   and quota_date = ? ";

            if (level == 4) {
                // 市级别
                sql += " and city = ? ";
            } else if (level == 3) {
                // 区、城镇级别
                sql += " and town = ? ";
            } else if (level == 2) {
                // 机构级别
                sql += " and org_code = ? ";
            } else if (level == 1) {
                sql += " and qkdoctor_code = ?";
            }

            List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, index, level, preDate, area);

            if (result != null && result.size() > 0) {
                total = (result.get(0).get("amount") != null ? Long.valueOf(result.get(0).get("amount").toString()) : 0L);
            }
        }

        return total;
    }

    /**
     * 获取三师转签或高危人群签约
     *
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     */
    public JSONObject getSszqAndGwrq(String endDate, String area, int level, String index) {
        JSONObject json = new JSONObject();

        // 查询语句
        String sql = " select " +
                "     ifnull(result,'0') amount" +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = ? " +
                "   and level1_type = ? and del = '1'";

        if (level == 4) {
            // 市级别
            sql += " and city = ? ";
        } else if (level == 3) {
            // 区、城镇级别
            sql += " and town = ? ";
        } else if (level == 2) {
            // 机构级别
            sql += " and org_code = ? ";
        } else if (level == 1) {
            sql += " and qkdoctor_code = ?";
        }
        sql += "   order by quota_date DESC " +
                "   limit 0,1";

        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, index, level, area);

        if (result != null && result.size() > 0) {
            String total = (result.get(0).get("amount") != null ? result.get(0).get("amount").toString() : "0");

            if (total.equals("0")) {
                json.put("amount", 0L);
                json.put("num", 0L);
                json.put("rate", 0.0000D);
            } else {
                DecimalFormat df = new DecimalFormat("0.0000");
                String[] args = total.split("/");
                json.put("amount", Long.valueOf(args[0]));
                json.put("num", Long.valueOf(args[1]));
                json.put("rate", df.format(Long.valueOf(args[0]) * 1.0000 / Long.valueOf(args[1]) * 100));
            }
        } else {
            json.put("amount", 0L);
            json.put("num", 0L);
            json.put("rate", 0.0000D);
        }

        return json;
    }

    /**
     * 获取缴费
     *
     * @param endDate 截止日期
     * @param area    区域
     * @param level   级别
     * @return
     */
    public long getWeiJiaoFei(String endDate, String area, int level) {
        long total = 0;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        boolean preFlag = false;
        String preDate = endDate;

        if (endDate.compareTo(dateFormat.format(new Date())) >= 0) {
            String val = "";
            try {
                val = redisTemplate.opsForValue().get("quota:16:" + level + ":" + area + ":0:" + getQuotaTimeStamp());
            } catch (Exception e) {
                val = "";
            }
            if (!StringUtils.isEmpty(val)) {
                JSONObject valJson = new JSONObject(val);
                if (valJson.has("num")) {
                    total = valJson.getInt("num");
                }
            } else {
                preFlag = true;
                Calendar today = Calendar.getInstance();
                today.add(Calendar.DATE, -1);
                preDate = dateFormat.format(today.getTime());
            }
        } else {
            preFlag = true;
        }
        if (preFlag) {
            // 查询语句
            String sql = " select " +
                    "     ifnull(result,'0') amount" +
                    " from  " +
                    "     wlyy_quota_result " +
                    " where " +
                    "     quato_code = '16' " +
                    "   and level1_type = ? and del = '1'" +
                    "   and level2_type = '0' " +
                    "   and quota_date = ? ";

            if (level == 4) {
                // 市级别
                sql += " and city = ? ";
            } else if (level == 3) {
                // 区、城镇级别
                sql += " and town = ? ";
            } else if (level == 2) {
                // 机构级别
                sql += " and org_code = ? ";
            } else if (level == 1) {
                sql += " and qkdoctor_code = ?";
            }

            List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, level, preDate, area);

            if (result != null && result.size() > 0) {
                total = (result.get(0).get("amount") != null ? Long.valueOf(result.get(0).get("amount").toString()) : 0L);
            }
        }

        return total;
    }

    /**
     * 查询截止某个日期累计签约率
     *
     * @param endDate 截止日期
     * @param area    区域或机构代码
     * @param level   级别
     * @return
     */
    public JSONObject getSignRate(String endDate, String area, int level, String year) throws Exception {
        JSONObject json = new JSONObject();
        long signAmount = getIndexTotal(endDate, area, level, "13");
        PopulationBase peopleNum = getPopulationBase(area, year);
        DecimalFormat df = new DecimalFormat("0.0000");

        if (peopleNum != null && peopleNum.getNum() > 0) {
            json.put("rate", df.format((signAmount * 1.0000) / peopleNum.getNum() * 100));
            json.put("rateString", signAmount + "/" + peopleNum.getNum());
            json.put("sign", signAmount);
            json.put("people", peopleNum.getNum());
        } else {
            json.put("rate", "0.0000");
            json.put("rateString", "0/0");
            json.put("sign", signAmount);
            json.put("people", 0);
        }

        return json;
    }

    /**
     * 查询截止某个日期签约完成率
     *
     * @param endDate 截止日期
     * @param area    区域或机构代码
     * @param level   级别
     * @return
     */
    public JSONObject getSignTaskRate(String endDate, String area, int level, String year) throws Exception {
        JSONObject json = new JSONObject();
        long signAmount = getIndexTotal(endDate, area, level, "13");
        PopulationBase peopleNum = getPopulationBase(area, year);
        DecimalFormat df = new DecimalFormat("0.0000");

        if (peopleNum != null && peopleNum.getTaskNum() > 0) {
            json.put("rate", df.format((signAmount * 1.0000) / peopleNum.getTaskNum() * 100));
            json.put("rateString", signAmount + "/" + peopleNum.getTaskNum());
            json.put("sign", signAmount);
            json.put("people", peopleNum.getTaskNum());
        } else {
            json.put("rate", "0.0000");
            json.put("rateString", "0/0");
            json.put("sign", signAmount);
            json.put("people", 0);
        }

        return json;
    }


    /**
     * 获取签约分组信息
     *
     * @param endDate
     * @param lowCode
     * @param area
     * @param level
     * @return
     */
    public JSONObject getGroupInfo(String endDate, String lowCode, String area, int level, String year) throws ParseException {
        JSONObject json = new JSONObject();
        long total = 0;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        boolean preFlag = false;
        String preDate = endDate;

        if (endDate.compareTo(dateFormat.format(new Date())) >= 0) {
            String val = "";
            try {
                val = redisTemplate.opsForValue().get("quota:17:" + level + ":" + area + ":" + lowCode + ":" + getQuotaTimeStamp());
            } catch (Exception e) {
                val = "";
            }
            if (!StringUtils.isEmpty(val)) {
                JSONObject valJson = new JSONObject(val);
                if (valJson.has("num")) {
                    total = valJson.getInt("num");
                }
            } else {
                preFlag = true;
                Calendar today = Calendar.getInstance();
                today.add(Calendar.DATE, -1);
                preDate = dateFormat.format(today.getTime());
            }
        } else {
            preFlag = true;
        }
        if (preFlag) {
            // 查询语句
            String sql = " select " +
                    "     ifnull(result,'0') amount" +
                    " from  " +
                    "     wlyy_quota_result " +
                    " where " +
                    "     quato_code = '17' " +
                    "   and level1_type = ? and del = '1'" +
                    "   and quota_date = ? " +
                    "   and level2_type = ? ";

            if (level == 4) {
                // 市级别
                sql += " and city = ? ";
            } else if (level == 3) {
                // 区、城镇级别
                sql += " and town = ? ";
            } else if (level == 2) {
                // 机构级别
                sql += " and org_code = ? ";
            } else if (level == 1) {
                sql += " and qkdoctor_code = ? ";
            }

            List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, level, preDate, lowCode, area);

            if (result != null && result.size() > 0) {
                total = (result.get(0).get("amount") != null ? Long.valueOf(result.get(0).get("amount").toString()) : 0L);
            }
        }

        int num = 0;
        int taskNum = 0;
        PopulationBase peopleNum = getPopulationBase(area, year);
        if (peopleNum != null) {
            if (lowCode.equals("3")) {
                num = peopleNum.getSixFiveNum();
                taskNum = peopleNum.getSixFiveTaskNum();
            } else if (lowCode.equals("1")) {
                num = peopleNum.getGxyNum();
                taskNum = peopleNum.getGxyTaskNum();
            } else if (lowCode.equals("2")) {
                num = peopleNum.getTnbNum();
                taskNum = peopleNum.getTnbTaskNum();
            }
        }


        DecimalFormat df = new DecimalFormat("0.0000");
        json.put("sign", total);
        JSONObject signRate = new JSONObject();
        signRate.put("sign", total);
        signRate.put("people", num);
        signRate.put("rate", df.format((total * 1.0000) / num * 100));
        signRate.put("rateString", total + "/" + num);
        json.put("signRate", signRate);
        JSONObject signTaskRate = new JSONObject();
        signTaskRate.put("sign", total);
        signTaskRate.put("people", taskNum);
        signTaskRate.put("rate", df.format((total * 1.0000) / taskNum * 100));
        signTaskRate.put("rateString", total + "/" + taskNum);
        json.put("signTaskRate", signTaskRate);

        return json;
    }

    /**
     * 查询某个级别的某个指标到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLevelTwoLowLevelTotal(String date, String area, int level, String index, int sort, String lowLevel, String lowCode, String year) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();

        if (date.compareTo(dateFormat.format(new Date())) >= 0) {
//            查询当天及以后的数据
            resultList = getLevelTwoTodayLowLevelTotal(area, level, index, sort, lowLevel, lowCode);
        } else {
//           查询当天以前的数据
            resultList = getLevelTwoTodayBeforeLowLevelTotal(date, area, level, index, sort, lowLevel, lowCode);
        }

        // 结果为空时,自建结果集
        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);

                if (!low_level.equals("1")) {
                    PopulationBase peopleNum = getPopulationBase(area, year);
                    if (peopleNum != null) {
                        int num = 0;
                        int taskNum = 0;

                        if (lowCode.equals("3")) {
                            num = peopleNum.getSixFiveNum();
                            taskNum = peopleNum.getSixFiveTaskNum();
                        } else if (lowCode.equals("1")) {
                            num = peopleNum.getGxyNum();
                            taskNum = peopleNum.getGxyTaskNum();
                        } else if (lowCode.equals("2")) {
                            num = peopleNum.getTnbNum();
                            taskNum = peopleNum.getTnbTaskNum();
                        }
                        map.put("rate", df.format(((long) map.get("amount") * 1.0000) / num * 100));
                        map.put("taskRate", df.format(((long) map.get("amount") * 1.0000) / taskNum * 100));
                        map.put("targetRate", df.format(taskNum * 1.0000 / num * 100));
                        map.put("rateString", map.get("amount") + "/" + num);
                        map.put("taskRateString", map.get("amount") + "/" + taskNum);
                        map.put("targetRateString", taskNum + "/" + num);
                        map.put("num", num);
                        map.put("task", taskNum);
                    }
                }
            }

            if ((level == 4 && "1".equals(lowLevel)) || (level == 2) || (level == 3 && "1".equals(lowLevel))) {
                translateTeamLeaderName(resultList);
            }

            Collections.sort(resultList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    long map1value = (long) o1.get("amount");
                    long map2value = (long) o2.get("amount");

                    if (map1value - map2value > 0) {
                        return sort == 1 ? -1 : 1;
                    } else if (map1value - map2value < 0) {
                        return sort == 1 ? 1 : -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 查询某个级别的某个指标到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLowLevelTotal(String date, String area, int level, String index, int sort, String lowLevel, String year) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();

        if (date.compareTo(dateFormat.format(new Date())) >= 0) {
            resultList = getTodayLowLevelTotal(area, level, index, sort, lowLevel);
        } else {
            resultList = getTodayBeforeLowLevelTotal(date, area, level, index, sort, lowLevel);
        }

        // 结果为空时,自建结果集
        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);

                if (!low_level.equals("1")) {
                    PopulationBase peopleNum = getPopulationBase(area, year);
                    if (peopleNum != null) {
                        map.put("rate", df.format(((long) map.get("amount") * 1.0000) / peopleNum.getNum() * 100));
                        map.put("taskRate", df.format(((long) map.get("amount") * 1.0000) / peopleNum.getTaskNum() * 100));
                        map.put("targetRate", df.format(peopleNum.getTaskNum() * 1.0000 / peopleNum.getNum() * 100));
                        map.put("rateString", map.get("amount") + "/" + peopleNum.getNum());
                        map.put("taskRateString", map.get("amount") + "/" + peopleNum.getTaskNum());
                        map.put("targetRateString", peopleNum.getTaskNum() + "/" + peopleNum.getNum());
                        map.put("num", peopleNum.getNum());
                        map.put("task", peopleNum.getTaskNum());
                    }
                }
            }

            if ((level == 4 && "1".equals(lowLevel)) || (level == 2)) {
                translateTeamLeaderName(resultList);
            }

            Collections.sort(resultList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    long map1value = (long) o1.get("amount");
                    long map2value = (long) o2.get("amount");

                    if (map1value - map2value > 0) {
                        return sort == 1 ? -1 : 1;
                    } else if (map1value - map2value < 0) {
                        return sort == 1 ? 1 : -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 13.17两个指标团队显示团队长
     * 查询某个级别的某个指标到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLowLevelTotalTeamLeader(String date, String area, int level, String index, int sort, String lowLevel, String year) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();

        if (date.compareTo(dateFormat.format(new Date())) >= 0) {
            resultList = getTodayLowLevelTotal(area, level, index, sort, lowLevel);
        } else {
            resultList = getTodayBeforeLowLevelTotal(date, area, level, index, sort, lowLevel);
        }

        // 结果为空时,自建结果集
        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            for (int i = 0; i < resultList.size(); i++) {
                Map<String, Object> map = resultList.get(i);
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);

                if (!low_level.equals("1")) {
                    String code = map.get("code").toString();
                    PopulationBase peopleNum = getPopulationBase(code, year);
                    if (peopleNum != null) {
                        map.put("rate", df.format(((long) map.get("amount") * 1.0000) / peopleNum.getNum() * 100));
                        map.put("taskRate", df.format(((long) map.get("amount") * 1.0000) / peopleNum.getTaskNum() * 100));
                        map.put("targetRate", df.format(peopleNum.getTaskNum() * 1.0000 / peopleNum.getNum() * 100));
                        map.put("rateString", map.get("amount") + "/" + peopleNum.getNum());
                        map.put("taskRateString", map.get("amount") + "/" + peopleNum.getTaskNum());
                        map.put("targetRateString", peopleNum.getTaskNum() + "/" + peopleNum.getNum());
                        map.put("num", peopleNum.getNum());
                        map.put("task", peopleNum.getTaskNum());
                    }
                }
            }

            if ((level == 4 && "1".equals(lowLevel)) || (level == 2) || (level == 3 && "1".equals(lowLevel))) {
                translateTeamLeaderName(resultList);
            }

            Collections.sort(resultList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    long map1value = (long) o1.get("amount");
                    long map2value = (long) o2.get("amount");

                    if (map1value - map2value > 0) {
                        return sort == 1 ? -1 : 1;
                    } else if (map1value - map2value < 0) {
                        return sort == 1 ? 1 : -1;
                    } else {
                        return 0;
                    }
                }
            });


            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }


    /**
     * 查询三师转签率、高危人群签约率
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLowLevelTotalSpecial(String date, String area, int level, String index, int sort, String lowLevel) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        String areaField = "";
        String lowLevelField = "";
        String lowLevelName = "";

//      查询日期参数是否存在于数据库
        String sql1 = "SELECT" +
                "   count(quota_date)" +
                "  FROM" +
                "   wlyy_quota_result" +
                "  where quota_date = ? and quato_code = ?";

        int rows = jdbcTemplate.queryForObject(sql1, Integer.class, date, index);
        if (rows == 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date tdate = sdf.parse(date);
            Calendar day = Calendar.getInstance();
            day.setTime(tdate);
            day.add(Calendar.DATE, -1);
            date = new SimpleDateFormat("yyyy-MM-dd").format(day.getTime());
        }

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            throw new Exception("param level error");
        }

        if (low_level.equals("3")) {
            lowLevelField = "town";
            lowLevelName = "town_name";
        } else if (low_level.equals("2")) {
            lowLevelField = "org_code";
            lowLevelName = "org_name";
        } else if (low_level.equals("1")) {
            lowLevelField = "qkdoctor_code";
            lowLevelName = "qkdoctor_name";
        } else {
            throw new Exception("param lowLevel error");
        }

        // 查询语句
        String sql = " select " +
                "     ifnull(" + lowLevelField + ",'') code " +
                "     ,ifnull(" + lowLevelName + ",'') 'name' " +
                "     ,ifnull(result,'0') amount" +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = ? and del = '1'" +
                "   and quota_date = ? " +
                "   and " + areaField + " = ? ";

        resultList = jdbcTemplate.queryForList(sql, low_level, date, area);

        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        for (Map<String, Object> map : resultList) {
            if (map.get("amount").toString().equals("0")) {
                map.put("amount", 0L);
                map.put("num", 0);
                map.put("rate", 0.0000D);
                map.put("rateString", "0/0");
            } else {
                DecimalFormat df = new DecimalFormat("0.0000");
                String[] args = map.get("amount").toString().split("/");

                map.put("amount", Long.valueOf(args[0]));
                map.put("num", Long.valueOf(args[1]));
                map.put("rate", df.format((Long.valueOf(args[0]) * 1.0000) / Long.valueOf(args[1]) * 100));
                map.put("rateString", args[0] + "/" + args[1]);
            }
        }

        if ((level == 4 && "1".equals(lowLevel)) || (level == 2)) {
            translateTeamLeaderName(resultList);
        }

        Collections.sort(resultList, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                String map1value = o1.get("rate").toString();
                String map2value = o2.get("rate").toString();

                if (map1value.compareTo(map2value) > 0) {
                    return sort == 1 ? -1 : 1;
                } else if (map1value.compareTo(map2value) < 0) {
                    return sort == 1 ? 1 : -1;
                } else {
                    return 0;
                }
            }
        });

        return new JSONArray(resultList);
    }


    /**
     * 获取过去某个日期某个区域一级指标的下级统计
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param lowLevel
     * @return
     */
    public List<Map<String, Object>> getLevelTwoTodayBeforeLowLevelTotal(String date, String area, int level, String index, int sort, String lowLevel, String lowCode) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        String areaField = "";
        String lowLevelField = "";
        String lowLevelName = "";

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            throw new Exception("param level error");
        }

        if (low_level.equals("3")) {
            lowLevelField = "town";
            lowLevelName = "town_name";
        } else if (low_level.equals("2")) {
            lowLevelField = "org_code";
            lowLevelName = "org_name";
        } else if (low_level.equals("1")) {
            lowLevelField = "qkdoctor_code";
            lowLevelName = "qkdoctor_name";
        } else {
            throw new Exception("param lowLevel error");
        }

        // 查询语句
        String sql = " select " +
                "     ifnull(" + lowLevelField + ",'') code " +
                "     ,ifnull(" + lowLevelName + ",'') 'name' " +
                "     ,ifnull(result,'0') amount" +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = ? and del = '1'" +
                "   and quota_date = ? " +
                "   and " + areaField + " = ? " +
                "   and level2_type = ? ";

        if (sort == 1) {
            sql += " order by amount desc ";
        } else {
            sql += " order by amount asc ";
        }

        resultList = jdbcTemplate.queryForList(sql, low_level, date, area, lowCode);

        return resultList;
    }

    /**
     * 获取过去某个日期某个区域一级指标的下级统计
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param lowLevel
     * @return
     */
    public List<Map<String, Object>> getTodayBeforeLowLevelTotal(String date, String area, int level, String index, int sort, String lowLevel) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        String areaField = "";
        String lowLevelField = "";
        String lowLevelName = "";

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            throw new Exception("param level error");
        }

        if (low_level.equals("3")) {
            lowLevelField = "town";
            lowLevelName = "town_name";
        } else if (low_level.equals("2")) {
            lowLevelField = "org_code";
            lowLevelName = "org_name";
        } else if (low_level.equals("1")) {
            lowLevelField = "qkdoctor_code";
            lowLevelName = "qkdoctor_name";
        } else {
            throw new Exception("param lowLevel error");
        }

        // 查询语句
        String sql = " select " +
                "     ifnull(" + lowLevelField + ",'') code " +
                "     ,ifnull(" + lowLevelName + ",'') 'name' " +
                "     ,ifnull(result,'0') amount" +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = ? and del = '1'" +
                "   and quota_date = ? " +
                "   and " + areaField + " = ? ";

        if (sort == 1) {
            sql += " order by amount desc";
        } else {
            sql += " order by amount asc ";
        }

        resultList = jdbcTemplate.queryForList(sql, low_level, date, area);

        return resultList;
    }


    /**
     * 获取今天及以后某个区域一级指标的下级统计
     *
     * @param area
     * @param level
     * @param index
     * @param lowLevel
     * @return 只返回当天的数据
     */
    public List<Map<String, Object>> getLevelTwoTodayLowLevelTotal(String area, int level, String index, int sort, String lowLevel, String lowCode) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        resultList = getLowLevelMapKey(level, low_level, area);
        boolean flag = false;

        for (Map<String, Object> map : resultList) {
            //String redisData = redisTemplate.opsForValue().get("quota:" + index + ":" + low_level + ":" + String.valueOf(map.get("code")) + ":" + lowCode + ":" + getQuotaTimeStamp());
            String redisData = "";
            try {
                redisData = redisTemplate.opsForValue().get("quota:" + index + ":" + low_level + ":" + String.valueOf(map.get("code")) + ":" + lowCode + ":" + getQuotaTimeStamp());
            } catch (Exception e) {
                redisData = "";
            }
            if (!StringUtils.isEmpty(redisData)) {
//                redisData不为空（从缓存中取出当天数据）
                JSONObject json = new JSONObject(redisData);
                map.put("amount", Long.valueOf(String.valueOf(json.get("num"))));
            } else {
//                redis中没有当天数据
                flag = true;
                resultList = new ArrayList<>();
                break;
            }
        }

        if (flag) {
            Calendar today = Calendar.getInstance();
            today.add(Calendar.DATE, -1);
            String preDate = new SimpleDateFormat("yyyy-MM-dd").format(today.getTime());
            resultList = getLevelTwoTodayBeforeLowLevelTotal(preDate, area, level, index, sort, lowLevel, lowCode);
        }

        return resultList;
    }

    /**
     * 获取今天某个区域一级指标的下级统计
     *
     * @param area
     * @param level
     * @param index
     * @param lowLevel
     * @return
     */
    public List<Map<String, Object>> getTodayLowLevelTotal(String area, int level, String index, int sort, String lowLevel) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        String redisData = "";
        try {
            redisData = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + low_level + ":" + getQuotaTimeStamp());
        } catch (Exception e) {
            redisData = "";
        }
        if (!StringUtils.isEmpty(redisData)) {
            JSONArray jsonArray = new JSONArray(redisData);

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject json = jsonArray.getJSONObject(i);
                Map<String, Object> data = new HashMap<>();

                data.put("code", String.valueOf(json.get("code")));
                data.put("name", String.valueOf(json.get("name")));
                data.put("amount", Long.valueOf(String.valueOf(json.get("num"))));

                resultList.add(data);
            }
        } else {
            Calendar today = Calendar.getInstance();
            today.add(Calendar.DATE, -1);
            String preDate = new SimpleDateFormat("yyyy-MM-dd").format(today.getTime());
            resultList = getTodayBeforeLowLevelTotal(preDate, area, level, index, sort, lowLevel);
        }

        if (resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        return resultList;
    }

    /**
     * 获取今天某个区域一级指标的下级统计
     *
     * @param area
     * @param level
     * @param index
     * @param lowLevel
     * @return
     */
    public List<Map<String, Object>> getTodayLowLevelTotal2(String area, int level, String index, int sort, String lowLevel) throws Exception {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        String redisData = "";
        try {
            redisData = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + low_level + ":" + getQuotaTimeStamp());
        } catch (Exception e) {
            redisData = "";
        }
        if (!StringUtils.isEmpty(redisData)) {
            JSONArray jsonArray = new JSONArray(redisData);

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject json = jsonArray.getJSONObject(i);
                Map<String, Object> data = new HashMap<>();

                data.put("code", String.valueOf(json.get("code")));
                data.put("name", String.valueOf(json.get("name")));
                data.put("amount", Long.valueOf(String.valueOf(json.get("num"))));

                resultList.add(data);
            }
        } else {
            Calendar today = Calendar.getInstance();
            today.add(Calendar.DATE, -1);
            String preDate = new SimpleDateFormat("yyyy-MM-dd").format(today.getTime());
            resultList = getTodayBeforeLowLevelTotal(preDate, area, level, index, sort, lowLevel);
        }

        if (resultList.size() < 1) {
            resultList = getLowLevelMapKey2(level, low_level, area);
        }

        return resultList;
    }


    /**
     * 获取下级统计key
     *
     * @param level
     * @param lowLevel
     * @param area
     * @return
     */
    public List<Map<String, Object>> getLowLevelMapKey(int level, String lowLevel, String area) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (lowLevel.equals("3")) {
            List<Town> towns = townDao.findByCityCode(area);
            if (towns != null) {
                for (Town town : towns) {
                    Map<String, Object> obj = new HashMap<>();
                    obj.put("code", town.getCode());
                    obj.put("name", town.getName());
                    obj.put("amount", "0");
                    resultList.add(obj);
                }
            }
        } else if (lowLevel.equals("2")) {
            List<Town> towns = new ArrayList<>();
            if (level == 4) {
                towns = townDao.findByCityCode(area);
            } else if (level == 3) {
                Town town = townDao.findByCode(area);
                if (town != null) {
                    towns.add(town);
                }
            }

            if (towns != null && towns.size() > 0) {
                for (Town town : towns) {
                    List<Hospital> hospitals = hospitalDao.findByTownCode(town.getCode());

                    for (Hospital hos : hospitals) {
                        if (hos.getCode().length() > 10) {
                            continue;
                        }
                        Map<String, Object> obj = new HashMap<>();
                        obj.put("code", hos.getCode());
                        obj.put("name", hos.getName());
                        obj.put("amount", "0");
                        resultList.add(obj);
                    }
                }
            }
        } else if (lowLevel.equals("1")) {
            List<Hospital> hospitals = new ArrayList<>();
            if (level == 4) {
                hospitals = hospitalDao.findByCity(area);
            } else if (level == 3) {
                hospitals = hospitalDao.findByTownCode(area);
            } else {
                Hospital hos = hospitalDao.findByCode(area);
                if (hos != null) {
                    hospitals.add(hos);
                }
            }

            if (hospitals != null && hospitals.size() > 0) {
                for (Hospital hos : hospitals) {
                    if (hos.getCode().length() > 10) {
                        continue;
                    }
                    List<AdminTeam> teams = adminTeamDao.findByOrgCode(hos.getCode());

                    for (AdminTeam team : teams) {
                        Map<String, Object> obj = new HashMap<>();
                        obj.put("code", String.valueOf(team.getId()));
                        obj.put("name", team.getName());
                        obj.put("amount", "0");
                        resultList.add(obj);
                    }
                }
            }
        }

        return resultList;
    }

    /**
     * 获取下级统计key
     *
     * @param level
     * @param lowLevel
     * @param area
     * @return
     */
    public List<Map<String, Object>> getLowLevelMapKey2(int level, String lowLevel, String area) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (lowLevel.equals("3")) {
            List<Town> towns = townDao.findByCityCode(area);
            if (towns != null) {
                for (Town town : towns) {
                    Map<String, Object> obj = new HashMap<>();
                    obj.put("code", town.getCode());
                    obj.put("name", town.getName());
                    obj.put("amount", 0L);
                    resultList.add(obj);
                }
            }
        } else if (lowLevel.equals("2")) {
            List<Town> towns = new ArrayList<>();
            if (level == 4) {
                towns = townDao.findByCityCode(area);
            } else if (level == 3) {
                Town town = townDao.findByCode(area);
                if (town != null) {
                    towns.add(town);
                }
            }

            if (towns != null && towns.size() > 0) {
                for (Town town : towns) {
                    List<Hospital> hospitals = hospitalDao.findByTownCode(town.getCode());

                    for (Hospital hos : hospitals) {
                        if (hos.getCode().length() > 10) {
                            continue;
                        }
                        Map<String, Object> obj = new HashMap<>();
                        obj.put("code", hos.getCode());
                        obj.put("name", hos.getName());
                        obj.put("amount", 0L);
                        resultList.add(obj);
                    }
                }
            }
        } else if (lowLevel.equals("1")) {
            List<Hospital> hospitals = new ArrayList<>();
            if (level == 4) {
                hospitals = hospitalDao.findByCity(area);
            } else if (level == 3) {
                hospitals = hospitalDao.findByTownCode(area);
            } else {
                Hospital hos = hospitalDao.findByCode(area);
                if (hos != null) {
                    hospitals.add(hos);
                }
            }

            if (hospitals != null && hospitals.size() > 0) {
                for (Hospital hos : hospitals) {
                    if (hos.getCode().length() > 10) {
                        continue;
                    }
                    List<AdminTeam> teams = adminTeamDao.findByOrgCode(hos.getCode());

                    for (AdminTeam team : teams) {
                        Map<String, Object> obj = new HashMap<>();
                        obj.put("code", String.valueOf(team.getId()));
                        obj.put("name", team.getName());
                        obj.put("amount", 0L);
                        resultList.add(obj);
                    }
                }
            }
        }

        return resultList;
    }


    /**
     * 获取二级指标的到达量
     *
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     */
    public JSONArray getIndexLevelTwototal(String endDate, String area, int level, String index) {
        String areaField = "";
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        List<Map<String, Object>> resultList = new ArrayList<>();

        if (endDate.compareTo(datef.format(new Date())) >= 0) {
            resultList = getTodayLevelTwoTotal(area, level, index);
        } else {
            resultList = getTodyBeforeLevelTwototal(endDate, area, level, index);
        }

        if (resultList != null) {
            long total = 0;

            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") == null ? 0 : Math.round(Double.valueOf(map.get("amount").toString())));

                if (index.equals("7")) {
                    // 分组指标总数算法
                    String code = map.get("code") != null ? String.valueOf(map.get("code")) : "";
                    if (code.equals("0") || code.equals("1") || code.equals("2") || code.equals("3") || code.equals("7")) {
                        total += (long) map.get("amount");
                    }
                } else if (index.equals("16")) {
                    String code = map.get("code") != null ? String.valueOf(map.get("code")) : "";

                    if (!code.equals("2")) {
                        total += (long) map.get("amount");
                    }
                } else {
                    total += (long) map.get("amount");
                }
            }

            if (!index.equals("8")) {
                DecimalFormat df = new DecimalFormat("0.0000");
                for (Map<String, Object> map : resultList) {
                    double rateG = (total > 0 ? ((long) map.get("amount")) * 1.0000 / total * 100 : 0);
                    map.put("rate", df.format(rateG));
                    map.put("rateString", map.get("amount") + "/" + total);
                }
            }
            if (index.equals("6") && resultList.size() > 0) {
                int i = 0;
                boolean flag = false;
                for (; i < resultList.size(); i++) {
                    if (resultList.get(i).get("code") != null && String.valueOf(resultList.get(i).get("code")).equals("3")
                            && String.valueOf(resultList.get(i).get("amount")).equals("0")) {
                        flag = true;
                        break;
                    }
                }
                if (flag) {
                    resultList.remove(i);
                }
            }
            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 获取二级指标的到达量
     *
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     */
    public List<Map<String, Object>> getTodyBeforeLevelTwototal(String endDate, String area, int level, String index) {
        String areaField = "";
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            // 团队
            areaField = "qkdoctor_code";
        }
        // 查询语句
        String sql = " select " +
                "     ifnull(level2_type,'') code " +
                "     ,ifnull(level2_type_name,'') 'name' " +
                "     ,ifnull(result,0.0) amount" +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = ? and del = '1'";


        sql += "   and quota_date = ? " +
                "   and " + areaField + " = ? " +
                " group by level2_type,level2_type_name";

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

        resultList = jdbcTemplate.queryForList(sql, level, endDate, area);

        if (resultList == null || resultList.size() < 1) {
            getLevelTwoMapKey(index);
        }

        return resultList;
    }


    /**
     * 查询某个指标的二级维度
     *
     * @param area
     * @param level
     * @param index
     * @return
     */
    public List<Map<String, Object>> getTodayLevelTwoTotal(String area, int level, String index) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String redisData = "";
        try {
            redisData = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + getQuotaTimeStamp());
        } catch (Exception e) {
            redisData = "";
        }
        if (!StringUtils.isEmpty(redisData)) {
            JSONArray jsonArray = new JSONArray(redisData);

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject json = jsonArray.getJSONObject(i);
                Map<String, Object> data = new HashMap<>();

                data.put("code", String.valueOf(json.get("code")));
                data.put("name", String.valueOf(json.get("name")));
                data.put("amount", Long.valueOf(String.valueOf(json.get("num"))));

                resultList.add(data);
            }
        } else {
            Calendar today = Calendar.getInstance();
            today.add(Calendar.DATE, -1);
            String preDate = new SimpleDateFormat("yyyy-MM-dd").format(today.getTime());
            resultList = getTodyBeforeLevelTwototal(preDate, area, level, index);
        }

        if (resultList.size() < 1) {
            resultList = getLevelTwoMapKey(index);
        }

        return resultList;
    }

    /**
     * 获取某个二级指标的统计key
     *
     * @param index
     * @return
     */
    public List<Map<String, Object>> getLevelTwoMapKey(String index) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (index.equals("6")) {
            Map<String, Object> women = new HashMap<>();
            women.put("code", "1");
            women.put("name", "女");
            women.put("amount", Double.valueOf("0.0"));
            resultList.add(women);

            Map<String, Object> man = new HashMap<>();
            man.put("code", "2");
            man.put("name", "男");
            man.put("amount", Double.valueOf("0.0"));
            resultList.add(man);

            Map<String, Object> unknown = new HashMap<>();
            unknown.put("code", "3");
            unknown.put("name", "未知");
            unknown.put("amount", Double.valueOf("0.0"));
            resultList.add(unknown);
        } else if (index.equals("7")) {
            Map<String, Object> nogroup = new HashMap<>();
            nogroup.put("code", "0");
            nogroup.put("name", "未分组");
            nogroup.put("amount", Double.valueOf("0.0"));
            resultList.add(nogroup);

            Map<String, Object> normal = new HashMap<>();
            normal.put("code", "1");
            normal.put("name", "普通人群");
            normal.put("amount", Double.valueOf("0.0"));
            resultList.add(normal);

            Map<String, Object> manbing = new HashMap<>();
            manbing.put("code", "2");
            manbing.put("name", "慢病人群65岁以下");
            manbing.put("amount", Double.valueOf("0.0"));
            resultList.add(manbing);

            Map<String, Object> upsixfive = new HashMap<>();
            upsixfive.put("code", "3");
            upsixfive.put("name", "65岁以上人群");
            upsixfive.put("amount", Double.valueOf("0.0"));
            resultList.add(upsixfive);

            Map<String, Object> gxy = new HashMap<>();
            gxy.put("code", "4");
            gxy.put("name", "高血压");
            gxy.put("amount", Double.valueOf("0.0"));
            resultList.add(gxy);

            Map<String, Object> tnb = new HashMap<>();
            tnb.put("code", "5");
            tnb.put("name", "糖尿病");
            tnb.put("amount", Double.valueOf("0.0"));
            resultList.add(tnb);

            Map<String, Object> tnbGxy = new HashMap<>();
            tnbGxy.put("code", "6");
            tnbGxy.put("name", "高血压和糖尿病");
            tnbGxy.put("amount", Double.valueOf("0.0"));
            resultList.add(tnb);

            Map<String, Object> mb65UpGxy = new HashMap<>();
            mb65UpGxy.put("code", "7");
            mb65UpGxy.put("name", "慢病人群65岁以上");
            mb65UpGxy.put("amount", Double.valueOf("0.0"));
            resultList.add(mb65UpGxy);
        } else if (index.equals("8")) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("code", "1");
            map1.put("name", "0~6");
            map1.put("amount", Double.valueOf("0.0"));
            resultList.add(map1);

            Map<String, Object> map2 = new HashMap<>();
            map2.put("code", "2");
            map2.put("name", "7~18");
            map2.put("amount", Double.valueOf("0.0"));
            resultList.add(map2);

            Map<String, Object> map3 = new HashMap<>();
            map3.put("code", "3");
            map3.put("name", "18~30");
            map3.put("amount", Double.valueOf("0.0"));
            resultList.add(map3);

            Map<String, Object> map4 = new HashMap<>();
            map4.put("code", "4");
            map4.put("name", "30~50");
            map4.put("amount", Double.valueOf("0.0"));
            resultList.add(map4);

            Map<String, Object> map5 = new HashMap<>();
            map5.put("code", "5");
            map5.put("name", "50~65");
            map5.put("amount", Double.valueOf("0.0"));
            resultList.add(map5);

            Map<String, Object> map6 = new HashMap<>();
            map6.put("code", "6");
            map6.put("name", "50~65");
            map6.put("amount", Double.valueOf("0.0"));
            resultList.add(map6);
        } else if (index.equals("16")) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("code", "0");
            map1.put("name", "未缴费人数");
            map1.put("amount", Double.valueOf("0.0"));
            resultList.add(map1);

            Map<String, Object> map2 = new HashMap<>();
            map2.put("code", "1");
            map2.put("name", "已缴费人数");
            map2.put("amount", Double.valueOf("0.0"));
            resultList.add(map2);

            Map<String, Object> map3 = new HashMap<>();
            map3.put("code", "2");
            map3.put("name", "已退费人数");
            map3.put("amount", Double.valueOf("0.0"));
            resultList.add(map3);
        } else if (index.equals("15")) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("code", "0");
            map1.put("name", "未标注");
            map1.put("amount", Double.valueOf("0.0"));
            resultList.add(map1);

            Map<String, Object> map2 = new HashMap<>();
            map2.put("code", "1");
            map2.put("name", "健康人群");
            map2.put("amount", Double.valueOf("0.0"));
            resultList.add(map2);

            Map<String, Object> map3 = new HashMap<>();
            map3.put("code", "2");
            map3.put("name", "患病人群");
            map3.put("amount", Double.valueOf("0.0"));
            resultList.add(map3);

            Map<String, Object> map4 = new HashMap<>();
            map4.put("code", "3");
            map4.put("name", "高危人群");
            map4.put("amount", Double.valueOf("0.0"));
            resultList.add(map4);

            Map<String, Object> map5 = new HashMap<>();
            map5.put("code", "4");
            map5.put("name", "恢复期人群");
            map5.put("amount", Double.valueOf("0.0"));
            resultList.add(map5);
        }

        return resultList;
    }


    /**
     * 统计65以上人群数据
     *
     * @param endDate
     * @param area
     * @param level
     * @return
     */
    public JSONArray getSixFiveStatistics(String endDate, String area, int level) {
        String areaField = "";
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        List<Map<String, Object>> resultList = new ArrayList<>();
        boolean preFlag = false;
        String preDate = endDate;

        if (endDate.compareTo(datef.format(new Date())) >= 0) {
            String redisData = "";
            try {
                redisData = redisTemplate.opsForValue().get("quota:12:" + level + ":" + area + ":6:" + getQuotaTimeStamp());
            } catch (Exception e) {
                redisData = "";
            }
            if (!StringUtils.isEmpty(redisData)) {
                JSONArray jsonArray = new JSONArray(redisData);

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject json = jsonArray.getJSONObject(i);
                    Map<String, Object> data = new HashMap<>();

                    data.put("code", json.getString("code"));
                    data.put("name", json.getString("name"));
                    data.put("amount", Long.valueOf(String.valueOf(json.get("num"))));

                    resultList.add(data);
                }
            } else {
                preFlag = true;
                Calendar today = Calendar.getInstance();
                today.add(Calendar.DATE, -1);
                preDate = datef.format(today.getTime());
            }
        } else {
            preFlag = true;
        }

        if (preFlag) {
            if (level == 4) {
                // 市级别
                areaField = "city";
            } else if (level == 3) {
                // 区、城镇级别
                areaField = "town";
            } else if (level == 2) {
                // 机构级别
                areaField = "org_code";
            } else if (level == 1) {
                // 团队
                areaField = "qkdoctor_code";
            }

            // 查询语句
            String sql = " select " +
                    "     ifnull(level3_type,'') code " +
                    "     ,ifnull(level3_type_name,'') 'name' " +
                    "     ,ifnull(result,0.0) amount" +
                    " from  " +
                    "     wlyy_quota_result " +
                    " where " +
                    "     quato_code = '12' " +
                    "   and level2_type = '6' " +
                    "   and level1_type = ? and del = '1'";


            sql += "   and quota_date = ? " +
                    "   and " + areaField + " = ? " +
                    " group by level3_type,level3_type_name";

            resultList = jdbcTemplate.queryForList(sql, level, preDate, area);
        }

        if (resultList == null || resultList.size() < 1) {
            resultList = new ArrayList<>();

            Map<String, Object> gxy = new HashMap<>();
            gxy.put("code", "1");
            gxy.put("name", "高血压");
            gxy.put("amount", Double.valueOf("0.0"));
            resultList.add(gxy);

            Map<String, Object> tnb = new HashMap<>();
            tnb.put("code", "2");
            tnb.put("name", "糖尿病");
            tnb.put("amount", Double.valueOf("0.0"));
            resultList.add(tnb);

            Map<String, Object> gxyTnb = new HashMap<>();
            gxyTnb.put("code", "3");
            gxyTnb.put("name", "高血压+糖尿病");
            gxyTnb.put("amount", Double.valueOf("0.0"));
            resultList.add(gxyTnb);

            Map<String, Object> jk = new HashMap<>();
            jk.put("code", "4");
            jk.put("name", "健康人群");
            jk.put("amount", Double.valueOf("0.0"));
            resultList.add(jk);
        }

        if (resultList != null) {
            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") == null ? 0 : Math.round(Double.valueOf(map.get("amount").toString())));
            }

            // 65岁以上人群总数统计
            long sixFiveTotal = getSixFiveTotal(endDate, area, level);
            Map<String, Object> sixFive = new HashMap<>();

            sixFive.put("code", "0");
            sixFive.put("name", "总数");
            sixFive.put("amount", sixFiveTotal);
            resultList.add(sixFive);

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 获取65岁以上人群总数
     *
     * @param endDate
     * @param area
     * @param level
     * @return
     */
    public long getSixFiveTotal(String endDate, String area, int level) {
        String areaField = "";
        long total = 0;
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        boolean preFlag = false;
        String preDate = endDate;

        if (endDate.compareTo(datef.format(new Date())) >= 0) {
            String code = "6";
            String val = "";
            try {
                val = redisTemplate.opsForValue().get("quota:8:" + level + ":" + area + ":" + code + ":" + getQuotaTimeStamp());
            } catch (Exception e) {
                val = "";
            }
            if (!StringUtils.isEmpty(val)) {
                JSONObject valJson = new JSONObject(val);
                if (valJson.has("num")) {
                    total = valJson.getInt("num");
                }
            } else {
                preFlag = true;
                Calendar today = Calendar.getInstance();
                today.add(Calendar.DATE, -1);
                preDate = datef.format(today.getTime());
            }
        } else {
            preFlag = true;
        }

        if (preFlag) {
            if (level == 4) {
                // 市级别
                areaField = "city";
            } else if (level == 3) {
                // 区、城镇级别
                areaField = "town";
            } else if (level == 2) {
                // 机构级别
                areaField = "org_code";
            } else if (level == 1) {
                // 团队
                areaField = "qkdoctor_code";
            }

            // 查询语句
            String sql = " select " +
                    "     ifnull(result,0.0) amount" +
                    " from  " +
                    "     wlyy_quota_result " +
                    " where " +
                    "     quato_code = '8' " +
                    "   and level2_type = '6' " +
                    "   and level1_type = ? and del = '1'";


            sql += "   and quota_date = ? " +
                    "   and " + areaField + " = ? ";

            List<Map<String, Object>> result = null;

            result = jdbcTemplate.queryForList(sql, level, preDate, area);

            if (result != null && result.size() > 0) {
                total = (result.get(0).get("amount") == null ? 0 : Math.round(Double.valueOf(result.get(0).get("amount").toString())));
            }
        }

        return total;
    }

    /**
     * 查询某个日期范围内的某个指标每天到达量
     *
     * @param startDate
     * @param endDate
     * @param interval
     * @param area
     * @param level
     * @param index
     * @return
     */
    public JSONObject getDateTotal(String startDate, String endDate, int interval, String area, int level, String index, String lowCode, String year) throws Exception {
        int taskNum = 0;
        JSONObject json = new JSONObject();

        if (level > 1 && StringUtils.isEmpty(lowCode)) {

            PopulationBase peopleNum = getPopulationBase(area, year);
            if (peopleNum != null) {
                taskNum = peopleNum.getTaskNum();
            }
        }
        if (!StringUtils.isEmpty(lowCode)) {
            PopulationBase peopleNum = getPopulationBase(area, year);
            if (peopleNum != null) {
                if (lowCode.equals("3")) {
                    taskNum = peopleNum.getSixFiveTaskNum();
                } else if (lowCode.equals("1")) {
                    taskNum = peopleNum.getGxyTaskNum();
                } else if (lowCode.equals("2")) {
                    taskNum = peopleNum.getTnbTaskNum();
                }
            }
        }

        json.put("taskNum", taskNum);

        if (interval == 1) {
            JSONArray jsonArray = dateTotalStatistics(startDate, endDate, area, level, index, lowCode);
            json.put("data", jsonArray);
            return json;
        } else if (interval == 2) {
            JSONArray jsonArray = weekTotalStatistics(startDate, endDate, area, level, index, lowCode);
            json.put("data", jsonArray);
            return json;
        } else if (interval == 3) {
            JSONArray jsonArray = monthTotalStatistics(startDate, endDate, area, level, index, lowCode);
            json.put("data", jsonArray);
            return json;
        }

        return json;
    }

    /**
     * @param startDate
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     */
    public JSONArray dateTotalStatistics(String startDate, String endDate, String area, int level, String index, String lowCode) throws ParseException {
        String areaField = "";
        String sql = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateCon = endDate;

        if (endDate.compareTo(df.format(new Date())) == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            dateCon = df.format(calendar.getTime());
        }

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            // 机构级别
            areaField = "qkdoctor_code";
        }

        // 起始日期
        Calendar start = Calendar.getInstance();
        start.setTime(DateUtil.strToDate(startDate, DateUtil.YYYY_MM_DD));
        //结束日期
        Calendar end = Calendar.getInstance();
        end.setTime(DateUtil.strToDate(endDate, DateUtil.YYYY_MM_DD));
        // 日期集合
        List<Calendar> days = new ArrayList<>();
        days.add(start);

        boolean flag = true;

        if (startDate.compareTo(endDate) == 0) {
            flag = false;
        }
        // 计算统计日期
        while (flag) {
            Calendar next = Calendar.getInstance();
            next.setTime(days.get(days.size() - 1).getTime());
            next.add(Calendar.DATE, 1);
            if (next.getTime().before(DateUtil.strToDate(endDate, "yyyy-MM-dd"))) {
                days.add(next);
            } else {
                days.add(end);
                flag = false;
            }
        }

        Map<String, JSONObject> countResult = new HashMap<>();

        // 统计预计构建
        for (int i = 0; i < days.size(); i++) {
            String startStr = "";
            long amount = 0;

            startStr = df.format(days.get(i).getTime());

            // 当前范围包含当天，则需添加当天的统计数据
            if (startStr.compareTo(df.format(new Date())) == 0) {
                String val = "";
                try {
                    val = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + (!StringUtils.isEmpty(lowCode) ? (lowCode + ":") : "") + getQuotaTimeStamp());
                } catch (Exception e) {
                    val = "";
                }
                if (!StringUtils.isEmpty(val)) {
                    JSONObject valJson = new JSONObject(val);
                    if (valJson.has("num")) {
                        amount = (long) valJson.getInt("num");
                    }
                }
            }

            JSONObject range = new JSONObject();
            range.put("range", startStr);
            range.put("amount", amount);
            countResult.put(startStr, range);
        }

        if (startDate.equals(df.format(new Date()))) {
            Calendar preDate = Calendar.getInstance();
            preDate.setTime(df.parse(endDate));
            preDate.add(Calendar.DATE, -1);

            startDate = df.format(preDate.getTime());
        }

        sql = " select " +
                "     ifnull(quota_date,'') as 'range' " +
                "     ,ifnull(result,'0') amount " +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = '" + level + "' and del = '1' " +
                "   and quota_date >= '" + startDate + "' " +
                "   and quota_date <= '" + dateCon + "' " +
                "   and " + areaField + " = '" + area + "' ";

        if (!StringUtils.isEmpty(lowCode)) {
            sql += "  and level2_type = '" + lowCode + "' ";
        }

        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql);

        if (resultList != null) {
            for (Map<String, Object> map : resultList) {
                if (countResult.containsKey(map.get("range").toString())) {
                    JSONObject range = countResult.get(map.get("range").toString());
                    long amount = range.getLong("amount");
                    long resultAmount = map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L;
                    range.put("amount", amount + resultAmount);
                }
            }

            List<JSONObject> result = new ArrayList<>(countResult.values());

            result.sort(new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    if (o1.getString("range").compareTo(o2.getString("range")) > 0) {
                        return 1;
                    } else if (o1.getString("range").compareTo(o2.getString("range")) < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(result);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 按周统计
     *
     * @param startDate
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     */
    private JSONArray weekTotalStatistics(String startDate, String endDate, String area, int level, String index, String lowCode) throws Exception {
        String areaField = "";
        String sql = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateCon = endDate;

        if (endDate.compareTo(df.format(new Date())) == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            dateCon = df.format(calendar.getTime());
        }

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            // 机构级别
            areaField = "qkdoctor_code";
        }

        // 起始日期
        Calendar start = Calendar.getInstance();
        start.setTime(DateUtil.strToDate(startDate, DateUtil.YYYY_MM_DD));
        // 第一个统计周期结束日期
        String firstEnd = "";
        // 结束日期
        Calendar end = Calendar.getInstance();
        end.setTime(DateUtil.strToDate(endDate, DateUtil.YYYY_MM_DD));
        // 起始日期为周几
        int week = start.get(Calendar.DAY_OF_WEEK);
        int incre = 7 - week + 1;

        // 日期集合
        List<Calendar> days = new ArrayList<>();
        days.add(start);
        boolean flag = true;
        int i = 0;

        if (startDate.compareTo(endDate) == 0) {
            flag = false;
            days.add(end);
            firstEnd = df.format(end.getTime());
        }

        // 计算统计日期
        while (flag) {
            Calendar next = Calendar.getInstance();
            next.setTime(days.get(days.size() - 1).getTime());

            if (i == 0) {
                if (incre != 7) {
                    next.add(Calendar.DATE, incre);
                }
            } else {
                next.add(Calendar.DATE, 7);
            }
            if (next.getTime().before(DateUtil.strToDate(endDate, "yyyy-MM-dd"))) {
                days.add(next);
                if (i == 0) {
                    firstEnd = df.format(next.getTime());
                }
            } else {
                days.add(end);
                flag = false;
                if (i == 0) {
                    firstEnd = df.format(end.getTime());
                }
            }

            i++;
        }

        // 结果集
        Map<String, JSONObject> countResult = new HashMap<>();

        // 算出每个查询周期
        for (int j = 0; j < days.size() - 1; j++) {
            String startStr = "";
            String endStr = df.format(days.get(j + 1).getTime());
            long amount = 0;

            // 起始、截止日期
            if (j == 0) {
                startStr = df.format(days.get(j).getTime());
            } else {
                Calendar cal = Calendar.getInstance();
                cal.setTime(days.get(j).getTime());
                cal.add(Calendar.DATE, 1);
                startStr = df.format(cal.getTime());
            }

            // 当前范围包含当天，则需添加当天的统计数据
            if (startStr.compareTo(df.format(new Date())) <= 0 && endStr.compareTo(df.format(new Date())) >= 0) {
                String val = "";
                try {
                    val = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + (!StringUtils.isEmpty(lowCode) ? (lowCode + ":") : "") + getQuotaTimeStamp());
                } catch (Exception e) {
                    val = "";
                }
                if (!StringUtils.isEmpty(val)) {
                    JSONObject valJson = new JSONObject(val);
                    if (valJson.has("num")) {
                        amount = valJson.getInt("num");
                    }
                }
            }

            JSONObject range = new JSONObject();

            range.put("range", endStr);
            range.put("amount", amount);

            countResult.put(endStr, range);
        }

        if (startDate.equals(df.format(new Date()))) {
            Calendar preDate = Calendar.getInstance();
            preDate.setTime(df.parse(endDate));
            preDate.add(Calendar.DATE, -1);

            startDate = df.format(preDate.getTime());
        }

        // 查询时间范围内所有记录
        sql = " select " +
                "     ifnull(quota_date,'') as 'range' " +
                "     ,ifnull(result,'0') amount " +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = '" + level + "' and del = '1' " +
                "   and quota_date >= '" + startDate + "' " +
                "   and quota_date <= '" + dateCon + "' " +
                "   and " + areaField + " = '" + area + "' ";

        if (!StringUtils.isEmpty(lowCode)) {
            sql += "  and level2_type = '" + lowCode + "' ";
        }

        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql);

        if (resultList != null) {
            // 计算结果
            for (Map<String, Object> map : resultList) {
                String range = map.get("range").toString();
                JSONObject json = countResult.get(range);

                if (json != null) {
                    long amount = map.get("amount") == null ? 0L : Long.valueOf(map.get("amount").toString());
                    json.put("amount", amount);
                }
            }

            List<JSONObject> result = new ArrayList<>(countResult.values());

            // 排序
            result.sort(new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    if (o1.getString("range").compareTo(o2.getString("range")) > 0) {
                        return 1;
                    } else if (o1.getString("range").compareTo(o2.getString("range")) < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(result);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 按月统计
     *
     * @param startDate
     * @param endDate
     * @param area
     * @param level
     * @param index
     * @return
     * @throws Exception
     */
    private JSONArray monthTotalStatistics(String startDate, String endDate, String area, int level, String index, String lowCode) throws Exception {
        String areaField = "";
        String sql = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateCon = endDate;

        if (endDate.compareTo(df.format(new Date())) == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            dateCon = df.format(calendar.getTime());
        }

        if (level == 4) {
            // 市级别
            areaField = "city";
        } else if (level == 3) {
            // 区、城镇级别
            areaField = "town";
        } else if (level == 2) {
            // 机构级别
            areaField = "org_code";
        } else if (level == 1) {
            // 机构级别
            areaField = "qkdoctor_code";
        }

        // 起始日期
        Calendar start = Calendar.getInstance();
        start.setTime(DateUtil.strToDate(startDate, DateUtil.YYYY_MM_DD));
        // 结束日期
        Calendar end = Calendar.getInstance();
        end.setTime(DateUtil.strToDate(endDate, DateUtil.YYYY_MM_DD));
        // 第一个结束日期
        String firstEnd = "";

        // 日期集合
        List<Calendar> days = new ArrayList<>();
        days.add(start);

        boolean flag = true;
        int k = 0;

        if (startDate.compareTo(endDate) == 0) {
            flag = false;
            days.add(end);
        }

        // 统计日期计算
        while (flag) {
            Calendar next = Calendar.getInstance();

            next.setTime(days.get(days.size() - 1).getTime());
            if (k == 0) {
                next.add(Calendar.MONTH, 1);
            } else {
                next.add(Calendar.MONTH, 2);
            }
            next.set(Calendar.DAY_OF_MONTH, 1);
            next.add(Calendar.DAY_OF_MONTH, -1);

            if (next.getTime().before(DateUtil.strToDate(endDate, "yyyy-MM-dd"))) {
                days.add(next);
            } else {
                days.add(end);
                flag = false;
            }
            k++;
        }

        // 统计结果
        Map<String, JSONObject> countResult = new HashMap<>();

        for (int i = 0; i < days.size() - 1; i++) {
            String startStr = "";
            String endStr = df.format(days.get(i + 1).getTime());
            int amount = 0;

            // 起始时间计算
            if (i == 0) {
                startStr = df.format(days.get(i).getTime());
            } else {
                Calendar cal = Calendar.getInstance();
                cal.setTime(days.get(i).getTime());
                cal.add(Calendar.DATE, 1);
                startStr = df.format(cal.getTime());
            }

            // 当天数据计算
            if (startStr.compareTo(df.format(new Date())) <= 0 && endStr.compareTo(df.format(new Date())) >= 0) {
                String val = "";
                try {
                    val = redisTemplate.opsForValue().get("quota:" + index + ":" + level + ":" + area + ":" + (!StringUtils.isEmpty(lowCode) ? (lowCode + ":") : "") + getQuotaTimeStamp());
                } catch (Exception e) {
                    val = "";
                }
                if (!StringUtils.isEmpty(val)) {
                    JSONObject valJson = new JSONObject(val);
                    if (valJson.has("num")) {
                        amount = valJson.getInt("num");
                    }
                }
            }

            JSONObject range = new JSONObject();

            range.put("range", endStr);
            range.put("amount", amount);

            countResult.put(endStr, range);
        }

        if (startDate.equals(df.format(new Date()))) {
            Calendar preDate = Calendar.getInstance();
            preDate.setTime(df.parse(endDate));
            preDate.add(Calendar.DATE, -1);

            startDate = df.format(preDate.getTime());
        }

        // 查询时间范围内所有记录
        sql = " select " +
                "     ifnull(quota_date,'') as 'range' " +
                "     ,ifnull(result,'0') amount " +
                " from  " +
                "     wlyy_quota_result " +
                " where " +
                "     quato_code = '" + index + "' " +
                "   and level1_type = '" + level + "' and del = '1' " +
                "   and quota_date >= '" + startDate + "' " +
                "   and quota_date <= '" + dateCon + "' " +
                "   and " + areaField + " = '" + area + "' ";

        if (!StringUtils.isEmpty(lowCode)) {
            sql += "  and level2_type = '" + lowCode + "' ";
        }

        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql);

        if (resultList != null) {
            String pre = "";
            if (endDate.equals(df.format(new Date()))) {
                Calendar preDate = Calendar.getInstance();
                preDate.setTime(df.parse(endDate));
                preDate.add(Calendar.DATE, -1);
                pre = df.format(preDate.getTime());
            }
            // 计算结果
            for (Map<String, Object> map : resultList) {
                String range = map.get("range").toString();
                JSONObject json = countResult.get(range);

                if (json != null) {
                    long amount = map.get("amount") == null ? 0L : Long.valueOf(map.get("amount").toString());
                    json.put("amount", amount);
                }
            }

            List<JSONObject> result = new ArrayList<>(countResult.values());

            // 排序
            result.sort(new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    if (o1.getString("range").compareTo(o2.getString("range")) > 0) {
                        return 1;
                    } else if (o1.getString("range").compareTo(o2.getString("range")) < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(result);
        } else {
            return new JSONArray();
        }
    }


    /**
     * 查询某个级别的某个指标到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLowLevelTotal2(String date, String area, int level, String index, int sort, String lowLevel) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();
        //获取微信关注的未交费
        Map<String, Integer> expenseStatus0 = getByIndex(date, area, level, "49", sort, lowLevel, dateFormat);
        //获取微信关注的已交费
        Map<String, Integer> expenseStatus1 = getByIndex(date, area, level, "50", sort, lowLevel, dateFormat);
        //获取已缴费的签约数
        Map<String, Integer> expenseStatus1Sigjn = getByIndex(date, area, level, "1", sort, lowLevel, dateFormat);


        // 结果为空时,自建结果集
        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            for (Map<String, Object> map : resultList) {
                Integer expenseStatus0amountNum = expenseStatus0.get(map.get("code").toString());
                Integer expenseStatus1amountNum = expenseStatus1.get(map.get("code").toString());
                Integer expenseStatus1SigjnNum = expenseStatus1Sigjn.get(map.get("code").toString());
                if (expenseStatus0amountNum == null) {
                    expenseStatus0amountNum = 0;
                }
                if (expenseStatus1amountNum == null) {
                    expenseStatus1amountNum = 0;
                }
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);
                map.put("weChatAmount0", expenseStatus0amountNum);//微信关注未交费数
                map.put("weChatAmount1", expenseStatus1amountNum);//微信关注已交费数
                map.put("signAccount", expenseStatus1SigjnNum);//签约已缴费的数目
                map.put("bindRate", getRangeDouuble(expenseStatus1amountNum, expenseStatus1SigjnNum, 2));//微信关注率

            }

            if ((level == 4 && "1".equals(lowLevel)) || (level == 2)) {
                translateTeamLeaderName(resultList);
            }
            //  排序 按绑定率来排序
            resultList.sort(new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    if ((double) o1.get("bindRate") >= (double) o2.get("bindRate")) {
                        return -1;
                    } else if ((double) o1.get("bindRate") < (double) o2.get("bindRate")) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 获取某个指标某一天某一level的值   到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @param dateFormat
     * @return
     * @throws Exception
     */
    private Map<String, Integer> getByIndex(String date, String area, int level, String index, int sort, String lowLevel, SimpleDateFormat dateFormat) throws Exception {
        Map<String, Integer> returnMap = new HashMap<>();
        List<Map<String, Object>> resultList;//获取未交费微信关注
        if (date.compareTo(dateFormat.format(new Date())) >= 0) {
            resultList = getTodayLowLevelTotal(area, level, index, sort, lowLevel);
        } else {
            resultList = getTodayBeforeLowLevelTotal(date, area, level, index, sort, lowLevel);
        }
        if (resultList != null && resultList.size() > 0) {
            resultList.stream().forEach(one -> {
                returnMap.put(one.get("code").toString(), Integer.valueOf(one.get("amount").toString()));
            });
        }
        return returnMap;
    }

    /**
     * 查询签约人数
     *
     * @param level
     * @param code
     * @return
     */
    public Long getQuoTaResult(int level, String code) {
        StringBuffer sql = new StringBuffer("SELECT t.result FROM wlyy_quota_result t WHERE t.quato_code ='1'AND t.quota_date = DATE_SUB(curdate(),INTERVAL 1 DAY) AND t.level1_type ='" + level + "'");
        if (level == 1) {
            //1:
            sql.append(" AND t.qkdoctor_code = '" + code + "'");
        } else if (level == 2) {
            //2社区机构
            sql.append(" AND t.org_code = '" + code + "'");
        } else if (level == 3) {
            //3区级
            sql.append(" AND t.town = '" + code + "'");
        } else if (level == 4) {
            //4市级
            sql.append(" AND t.city = '" + code + "'");
        }
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql.toString());

        if (resultList != null && resultList.size() > 0) {
            return Long.parseLong((String) resultList.get(0).get("result"));
        }

        return 0L;
    }

    /**
     * 获取所有团队长信息
     *
     * @return
     */
    public Map<Integer, Map<String, Object>> getAllTeamLeaders() {
        String sql = " select t.leader_code,t.id,d.name " +
                " from wlyy_admin_team t " +
                " LEFT JOIN wlyy_doctor d " +
                " on t.leader_code = d.code ";
        List<Map<String, Object>> rs = jdbcTemplate.queryForList(sql);
        //将结果集转换为 map减小循环层
        Map<Integer, Map<String, Object>> rsMap = new HashMap<>();
        if (rs != null && rs.size() > 0) {
            for (Map<String, Object> map : rs) {
                rsMap.put((Integer) map.get("id"), map);
            }
        }
        return rsMap;
    }

    /**
     * 获取团队长队长名字
     *
     * @param leaders
     * @param teamCode
     * @return
     */
    public String getTeamLeaderNameByTeamCode(Map<Integer, Map<String, Object>> leaders, int teamCode) {
        if (leaders != null && leaders.size() > 0 && teamCode != 0) {
            Map<String, Object> leader = leaders.get(teamCode);
            if (leader != null) {
                return (String) leader.get("name");
            }
        }
        return "";
    }

    public List<Map<String, Object>> translateTeamLeaderName(List<Map<String, Object>> rs) {
        Map<Integer, Map<String, Object>> leaders = getAllTeamLeaders();
        if (rs != null && rs.size() > 0) {
            for (Map<String, Object> r : rs) {
                String id = (String) r.get("code");
                String name = getTeamLeaderNameByTeamCode(leaders, Integer.parseInt(id));
                if (org.apache.commons.lang3.StringUtils.isNotBlank(name)) {
                    r.put("name", name);
                }
            }
        }
        return rs;
    }

    public JSONArray translateTeamLeaderName(JSONArray rs) {
        Map<Integer, Map<String, Object>> leaders = getAllTeamLeaders();
        if (rs != null) {
            for (int i = 0; i < rs.length(); i++) {
                JSONObject r = rs.getJSONObject(i);
                Integer id = (Integer) r.get("id");
                String name = getTeamLeaderNameByTeamCode(leaders, id);
                if (org.apache.commons.lang3.StringUtils.isNotBlank(name)) {
                    r.put("name", name);
                }
            }
        }
        return rs;
    }

    public JSONArray translateTeamLeaderNameByCode(JSONArray rs) {
        Map<Integer, Map<String, Object>> leaders = getAllTeamLeaders();
        if (rs != null) {
            for (int i = 0; i < rs.length(); i++) {
                JSONObject r = rs.getJSONObject(i);
                String id = (String) r.get("code");
                String name = getTeamLeaderNameByTeamCode(leaders, Integer.parseInt(id));
                if (org.apache.commons.lang3.StringUtils.isNotBlank(name)) {
                    r.put("name", name);
                }
            }
        }
        return rs;
    }

    public List<AdminTeam> translateAdminTeamLeaderName(List<AdminTeam> rs) {
        Map<Integer, Map<String, Object>> leaders = getAllTeamLeaders();
        if (rs != null && rs.size() > 0) {
            for (AdminTeam team : rs) {
                Integer id = team.getId().intValue();
                String name = getTeamLeaderNameByTeamCode(leaders, id);
                if (org.apache.commons.lang3.StringUtils.isNotBlank(name)) {
                    team.setName(name);
                }
            }
        }
        return rs;
    }


    /**
     * 查询某个级别的某个指标到达量
     *
     * @param date
     * @param area
     * @param level
     * @param index
     * @param sort
     * @param lowLevel
     * @return
     * @throws Exception
     */
    public JSONArray getLevelTwoLowLevelTotalTeamLeader(String date, String area, int level, String index, int sort, String lowLevel, String lowCode, String year) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();

        if (date.compareTo(dateFormat.format(new Date())) >= 0) {
//            查询当天及以后的数据
            resultList = getLevelTwoTodayLowLevelTotal(area, level, index, sort, lowLevel, lowCode);
        } else {
//           查询当天以前的数据
            resultList = getLevelTwoTodayBeforeLowLevelTotal(date, area, level, index, sort, lowLevel, lowCode);
        }

        // 结果为空时,自建结果集
        if (resultList == null || resultList.size() < 1) {
            resultList = getLowLevelMapKey(level, low_level, area);
        }

        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);

                if (!low_level.equals("1")) {
                    PopulationBase peopleNum = getPopulationBase(map.get("code").toString(), year);
                    if (peopleNum != null) {
                        int num = 0;
                        int taskNum = 0;

                        if (lowCode.equals("3")) {
                            num = peopleNum.getSixFiveNum();
                            taskNum = peopleNum.getSixFiveTaskNum();
                        } else if (lowCode.equals("1")) {
                            num = peopleNum.getGxyNum();
                            taskNum = peopleNum.getGxyTaskNum();
                        } else if (lowCode.equals("2")) {
                            num = peopleNum.getTnbNum();
                            taskNum = peopleNum.getTnbTaskNum();
                        }
                        map.put("rate", df.format(((long) map.get("amount") * 1.0000) / num * 100));
                        map.put("taskRate", df.format(((long) map.get("amount") * 1.0000) / taskNum * 100));
                        map.put("targetRate", df.format(taskNum * 1.0000 / num * 100));
                        map.put("rateString", map.get("amount") + "/" + num);
                        map.put("taskRateString", map.get("amount") + "/" + taskNum);
                        map.put("targetRateString", taskNum + "/" + num);
                        map.put("num", num);
                        map.put("task", taskNum);
                    }
                }
            }
            if ((level == 4 && "1".equals(lowLevel)) || (level == 2) || (level == 3 && "1".equals(lowLevel))) {
                translateTeamLeaderName(resultList);
            }

            Collections.sort(resultList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    long map1value = (long) o1.get("amount");
                    long map2value = (long) o2.get("amount");

                    if (map1value - map2value > 0) {
                        return sort == 1 ? -1 : 1;
                    } else if (map1value - map2value < 0) {
                        return sort == 1 ? 1 : -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    public String getRange(int first, int second, int i) {
        if (second == 0 && first > 0) {
            //如果分母为0 分子不为0 返回100%
            return "100%";
        } else if (second == 0 && first == 0) {
            //如果分母为0 分子为0 返回0%
            return "0%";
        }
        float size = (float) (first * 100) / second;
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数，不足的补0
        String filesize = df.format(size);
        return filesize + "%";
    }

    public double getRangeDouuble(int first, int second, int i) {
        if (second == 0 && first > 0) {
            //如果分母为0 分子不为0 返回100%
            return 100;
        } else if (second == 0 && first == 0) {
            //如果分母为0 分子为0 返回0%
            return 0;
        }
        float size = (float) (first * 100) / second;
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数，不足的补0
        String filesize = df.format(size);
        return Double.valueOf(filesize);
    }

    public JSONArray getLevelTwoLowLevelTotalSignAndRenew(String area, int level, String index, int sort, String lowLevel, String year) throws Exception {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String lastDate = year + "-06-30";
        String timeKey = redisTemplate.opsForValue().get("quota:timeKey");

        String low_level = String.valueOf(StringUtils.isEmpty(lowLevel) ? (level - 1) : lowLevel);
        List<Map<String, Object>> resultList = new ArrayList<>();//续签量
        //从redis获取续签量列表 团队，机构 区的续签量根据index来区分
        JSONArray renewJA = getLevel2ListForRedis(index, level + "", lowLevel, area, timeKey);

        //续签的的列表转map
        Map<String, Integer> renewMap = new HashMap<>();
        if (renewJA != null && renewJA.length() > 0) {
            for (int i = 0; i < renewJA.length(); i++) {
                JSONObject jo = renewJA.getJSONObject(i);
                renewMap.put(jo.getString("code"), jo.getInt("num"));
            }
        }
        //自建结果集
        resultList = getLowLevelMapKey(level, low_level, area);


        if (resultList != null) {
            DecimalFormat df = new DecimalFormat("0.0000");
            //查询去年的签约转map
            List<WlyyQuotaResult> yearsYear = findQuotaResultList(lastDate, Integer.valueOf(low_level), "1");
            Map<String, WlyyQuotaResult> resultMap = new HashMap<>();
            yearsYear.stream().forEach(one -> {
                if ("1".equals(low_level)) {
                    resultMap.put(one.getQkdoctorCode(), one);
                } else if ("2".equals(low_level)) {
                    resultMap.put(one.getOrgCode(), one);
                } else if ("3".equals(low_level)) {
                    resultMap.put(one.getTown(), one);
                }
            });

            for (Map<String, Object> map : resultList) {
                map.put("amount", map.get("amount") != null ? Long.valueOf(map.get("amount").toString()) : 0L);
                //获取去年签约的人数 默认是上个年度的最后一天
                WlyyQuotaResult one=resultMap.get(map.get("code").toString());
                int signNum = 0;
                int renewNum = renewMap.get(map.get("code").toString());
                if(one!=null){
                    signNum=Integer.valueOf(one.getResult());
                }
                map.put("rate", getRange(renewNum, signNum, 2));//续签率是 续签量/去年的签约数
                map.put("signNum", signNum);
                map.put("renewNum", renewNum);

            }

            if ((level == 4 && "1".equals(lowLevel)) || (level == 2) || (level == 3 && "1".equals(lowLevel))) {
                translateTeamLeaderName(resultList);
            }
            //对结果进行排序
            Collections.sort(resultList, new Comparator<Map<String, Object>>() {
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    int map1value = (int) o1.get("renewNum");
                    int map2value = (int) o2.get("renewNum");

                    if (map1value - map2value > 0) {
                        return sort == 1 ? -1 : 1;
                    } else if (map1value - map2value < 0) {
                        return sort == 1 ? 1 : -1;
                    } else {
                        return 0;
                    }
                }
            });

            return new JSONArray(resultList);
        } else {
            return new JSONArray();
        }
    }

    /**
     * 获取单个数据
     *
     * @param date
     * @param level
     * @param index
     * @return
     */
    public List<WlyyQuotaResult> findQuotaResultList(String date, int level, String index) {
        String sql = " select * from wlyy_quota_result w where " +
                " w.quota_date ='" + date + "' and " +
                " w.quato_code='" + index + "' and " +
                " w.level1_type= " + level;
        List<WlyyQuotaResult> results = jdbcTemplate.query(sql, new BeanPropertyRowMapper(WlyyQuotaResult.class));
        return results;
    }
    //================================通用接口=============================

    /**
     * 查询redis中父子表是level 的某个level2的列表
     *
     * @param index
     * @param level
     * @param level2
     * @param code
     * @param timeKey
     * @return
     */
    private JSONArray getLevel2ListForRedis(String index, String level, String level2, String code, String timeKey) {
        String key37 = "quota:" + index + ":" + level + ":" + code + ":" + level2 + ":" + timeKey;
        String value = redisTemplate.opsForValue().get(key37);
        JSONArray switchJo = new JSONArray(value);
        return switchJo;
    }

    public PopulationBase getPopulationBase(String code, String year) {

        String sql = "select * from wlyy_people_num where code=? and year=? ";
        List<PopulationBase> peopleNum = jdbcTemplate.query(sql, new BeanPropertyRowMapper(PopulationBase.class), code, year);
        return peopleNum.get(0);
    }
}
