/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.yihu.wlyy.service.common.account;

import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.doctor.team.admin.AdminTeam;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorPatient;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.ServerLabelTree;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.entity.patient.SignFamilyRenew;
import com.yihu.wlyy.entity.security.Token;
import com.yihu.wlyy.repository.doctor.DoctorAdminTeamDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.doctor.DoctorPatientDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.repository.security.TokenDao;
import com.yihu.wlyy.task.SignSsGetTask;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.EncodesUtil;
import com.yihu.wlyy.util.IdcardInfoExtractor;
import com.yihu.wlyy.util.SystemData;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.utils.Clock;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 患者基本信息类.
 *
 * @author George
 */
@Component
@Transactional(rollbackFor = Exception.class)
public class PatientService extends TokenService {

    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private DoctorPatientDao doctorPatientDao;
    @Autowired
    private DoctorAdminTeamDao doctorAdminTeamDao;
    @Autowired
    TokenDao tokenDao;
    @Autowired
    JdbcTemplate jdbcTemplate;

    private Clock clock = Clock.DEFAULT;
    //可续签月份
    private int[] canRenewMonth = {4, 5, 6, 7};

    public void setClock(Clock clock) {
        this.clock = clock;
    }

    public Patient findByCode(String code) {
        return patientDao.findByCode(code);
    }

    public Patient findByIdcard(String idcard) {
        return patientDao.findByIdcard(idcard);
    }

    public Patient findBySsc(String ssc) {
        return patientDao.findBySsc(ssc);
    }

    public List<Patient> findByMobile(String mobile) {
        return patientDao.findByMobile(mobile);
    }

    public Patient findByOpenid(String openid) {
        return patientDao.findByOpenid(openid);
    }

    public int countByOpenid(String openid) {
        return patientDao.countByOpenid(openid);
    }

    /**
     * 修改患者密码
     *
     * @param patient
     */
    public void updatePatientPwd(Patient patient) {
        patientDao.save(patient);
    }

    public void updatePatientInfo(Patient patient) {
        patientDao.save(patient);
    }

    /**
     * 修改患者openid
     *
     * @param patient
     */
    public void updatePatient(Patient patient, String openid) throws Exception {
        Sort sort = new Sort(Sort.Direction.ASC, "czrq");
        PageRequest pageRequest = new PageRequest(0, 100, sort);
        Page<Token> tokens = tokenDao.findByOpenid(openid, pageRequest);

        if (tokens != null && tokens.getContent().size() >= 10) {
            int i = 0;
            int last = tokens.getContent().size() - 10;
            for (Token token : tokens) {
                i++;
                Patient p = patientDao.findByCode(token.getUser());
                if (p == null || i <= last) {
                    tokenDao.delete(token);
                    SystemData.wxPatientTokens.remove(token.getUser());
                    continue;
                }
                p.setOpenid("");
                p.setOpenidTime(null);
                signFamilyDao.updateOpenidByPatient("", p.getCode());
                patientDao.save(p);
                tokenDao.delete(token);
                SystemData.wxPatientTokens.remove(p.getCode());
                break;
            }
        }
        //如果之前患者的openId为空并且openID有值更新时间
        if (!org.springframework.util.StringUtils.isEmpty(openid) && org.springframework.util.StringUtils.isEmpty(patient.getOpenid())) {
            patient.setOpenidTime(new Date());
        }
        //System.out.println("========openid=======");
        patient.setOpenid(openid);
        Patient ps = patientDao.save(patient);
        System.out.print(new JSONObject(ps));
        if (StringUtils.isNotEmpty(patient.getOpenid())) {
            signFamilyDao.updateOpenidByPatient(patient.getOpenid(), patient.getCode());
        }
    }

    public void deletePatient(Patient patient) {
        patientDao.delete(patient);
    }

    public void deletePatients(Iterable<Patient> patients) {
        patientDao.delete(patients);
    }

    /**
     * 患者註冊
     *
     * @param patient
     * @return
     * @throws Exception
     */
    public JSONObject register_bak(Patient patient, String imei, int platform) throws Exception {
        IdcardInfoExtractor ie = new IdcardInfoExtractor(patient.getIdcard());
        patient.setBirthday(ie.getBirthday());
        patient.setSex(ie.getGender());
        patient.setCode(getCode());
        patient.setStatus(1);
        patient.setCzrq(clock.getCurrentDate());
        patient.setDisease(0);
        patient.setDiseaseCondition(0);
        patient.setRecordAmount(0);
        patient.setPoints(0);
        patient.setOpenid("");
        Patient temp = patientDao.save(patient);
        if (temp != null) {
            // 更新openid
            updatePatient(temp, imei);
            // 生成登录tokey
            Token token = newToken(temp.getCode(), imei, platform);
            if (token != null) {
                // 生成登录信息成功
                JSONObject json = new JSONObject();
                json.put("id", temp.getId());
                json.put("uid", temp.getCode());
                json.put("token", token.getToken());
                json.put("name", temp.getName());
                json.put("photo", temp.getPhoto());
                //new Thread(new SignSsGetTask(patient.getIdcard())).start();
                return json;
            }
        }
        return null;
    }

    /**
     * 患者注册
     *
     * @param idcard
     * @param ssc
     * @param name
     * @param mobile
     * @param password
     * @param salt
     * @param imei
     * @param platform
     * @return
     * @throws Exception
     */
    public JSONObject register(String idcard, String ssc, String name, String mobile
            , String password, String salt, String imei, int platform) throws Exception {
        IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
        String code = getCode();
        String sql = "insert wlyy_patient(code,idcard,name,ssc,mobile,password,salt,openid" +
                ",status,birthday,sex,czrq,openid_time,disease,disease_condition,record_amount,points)" +
                " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE idcard = ?";

        jdbcTemplate.update(sql, new Object[]{code, idcard, name, ssc, mobile, password, salt, imei, 1, ie.getBirthday()
                , ie.getGender(), clock.getCurrentDate(), clock.getCurrentDate(), 0, 0, 0, 0, idcard});

        Patient temp = patientDao.findByIdcard(idcard);
        if (temp != null) {
            // 更新openid
            updatePatient(temp, imei);
            // 生成登录tokey
            Token token = newToken(temp.getCode(), imei, platform);
            if (token != null) {
                // 生成登录信息成功
                JSONObject json = new JSONObject();
                json.put("id", temp.getId());
                json.put("uid", temp.getCode());
                json.put("token", token.getToken());
                json.put("name", temp.getName());
                json.put("photo", temp.getPhoto());
                //new Thread(new SignSsGetTask(patient.getIdcard())).start();
                return json;
            }
        }
        return null;
    }

    /**
     * 建立三师团队与患者的关系
     *
     * @param sf
     * @param patient
     * @param doctorCode
     * @param doctorType
     */
    private void bindDoctorPatient(SignFamily sf, Patient patient, String doctorCode, int doctorType) {
        DoctorPatient dp = doctorPatientDao.findByPatientDoctorTeamType(patient.getCode(), doctorCode, doctorType);
        if (dp == null) {
            Doctor doctor = doctorDao.findByCode(doctorCode);
            dp = new DoctorPatient();
            dp.setBirthday(patient.getBirthday());
            dp.setCzrq(new Date());
            dp.setDoctor(doctor.getCode());
            dp.setDoctorName(doctor.getName());
            // 健康管理师
            dp.setDoctorType(doctorType);
            dp.setPatient(patient.getCode());
            dp.setPatientName(patient.getName());
            dp.setSex(patient.getSex());
            if (sf != null) {
                // 三师和家庭都存在
                dp.setSignType("11");
            } else {
                // 只有家庭签约
                dp.setSignType("01");
            }
            dp.setStatus(1);
            // 设置为三师团队
            dp.setTeamType(1);
            // 保存到数据库
            doctorPatientDao.save(dp);
        }
    }

    /**
     * 微信端患者註冊
     *
     * @param patient
     * @return
     * @throws Exception
     */
    public JSONObject register(Patient patient) throws Exception {
        patient.setCode(getCode());
        patient.setCzrq(clock.getCurrentDate());
        EncodesUtil.entryptPassword(patient);
        Patient temp = patientDao.save(patient);
        if (temp != null) {
            JSONObject json = new JSONObject();
            json.put("id", temp.getId());
            json.put("uid", temp.getCode());
            json.put("name", "");
            json.put("openid", temp.getOpenid());
            return json;
        }
        return null;
    }

    /**
     * 判断是否续签
     *
     * @param patient
     * @return
     */
    public JSONObject checkCanRenew(String patient) {
        // 是否可以续签逻辑
        //A：wlyy_sign_family
        //B: wlyy_sign_family_renew
        //签约状态(-1患者已取消，-2已拒绝，-3已解约，-4已到期，0待签约，1已签约，2患者申请取消签约，3医生申请取消签约
        //扣费状态 【0未扣费 1已扣费 2已退费】

        JSONObject rs = new JSONObject();
        //判断是否签约
        List<SignFamily> signs = jdbcTemplate.queryForList("SELECT t.id FROM wlyy_sign_family t WHERE t.status >=0 AND t.expenses_status ='1' AND  t.patient ='" + patient + "'  AND NOW() >= t.begin AND NOW() <= t.end", SignFamily.class);
        if (signs != null) {
            //当前年度已经签约
            rs.put("issign", "1");
        } else {
            //当前年度未签约
            rs.put("issign", "0");
        }

        //A表有已签约，但还没有扣费的记录的，不允许续签
        List<SignFamily> signFamilys1 = jdbcTemplate.queryForList("SELECT t.id FROM wlyy_sign_family t WHERE t.status >=0 AND t.expenses_status <>'1' AND t.patient ='" + patient + "'", SignFamily.class);
        if (signFamilys1 != null) {
            rs.put("isrenew", "0");
            return rs;
        }

        //A表有已签约，且已扣费，当前日期超过了7月1日，且当前日期在合约的有效期范围内，不允许续签
        Calendar calendar = Calendar.getInstance();
        String year = calendar.get(Calendar.YEAR) + "";
        List<SignFamily> signFamilys2 = jdbcTemplate.queryForList("SELECT t.id FROM wlyy_sign_family t WHERE t.status >=0 AND t.expenses_status ='1' AND  t.patient ='" + patient + "' AND CURDATE()>'" + year + "-07-01' NOW() >= t.begin and NOW() <= t.end", SignFamily.class);
        if (signFamilys2 != null) {
            rs.put("isrenew", "0");
            return rs;
        }

        //B表：已签约且未生效,不允许续签
        List<SignFamilyRenew> signFamilyRenews = jdbcTemplate.queryForList("SELECT t.id FROM wlyy_sign_family_renew t WHERE t.status>=0 AND  t.is_valid = 0 AND t.patient ='" + patient + "'", SignFamilyRenew.class);
        if (signFamilyRenews != null) {
            rs.put("isrenew", "0");
            return rs;
        }
        //都未有记录则允许续签
        rs.put("isrenew", "1");
        return rs;
    }

    /**
     * 判断是否可以续签
     * @param patient
     * @return
     */
    public JSONObject checkCanSignRenew(String patient) {

        JSONObject rs = new JSONObject();
        //得到当前年度,和当前月份,年度
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        //判断是否在续签允许的范围内
        boolean flag = false;
        for (int i = 0; i < canRenewMonth.length; i++) {
            if (month == canRenewMonth[i]) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            rs.put("mes", "当前时间段不允许续签");
            rs.put("code", "-1");
            return rs;
        }
        //判断是否有生效记录SQL
        String sql = "SELECT t.id,t.sign_year signYear FROM wlyy_sign_family t WHERE t.patient ='" + patient + "' AND t.status>=0 AND t.expenses_status='1'";
        //用于判断续签表是否有记录QL,有记录则不允许续签
        String sqlRenew = "SELECT t.id,t.sign_year signYear,t.status FROM wlyy_sign_family_renew t WHERE t.patient ='" + patient + "' AND t.status>=0 ";
        //判读是否有当前年度的记录SQL
        String signSql = "SELECT t.id,t.sign_year signYear ,t.status  FROM wlyy_sign_family t WHERE t.patient ='" + patient + "' AND t.status>=0  AND t.sign_year ='" + year + "'";
        //判读是否有旧的已到期记录SQL
        String oldSignSql = "SELECT t.id,t.sign_year signYear,t.status FROM wlyy_sign_family t WHERE t.patient ='" + patient + "' AND t.status=-4 AND  t.expenses_status='1' AND t.sign_year ='" + (year - 1) + "'";
        //判断时间是否在6月30之前
        if (month < 7) {
            //判断是否有签约记录
            List<Map<String,Object>> signFamilys1 = jdbcTemplate.queryForList(sql);
            if (signFamilys1 != null && signFamilys1.size() > 0) {
                //如果有记录则判断其年份是否为当前年份,如果为当前年份,不允许续签
                Map<String,Object> sign = signFamilys1.get(0);

                if (StringUtils.isNotBlank((String)sign.get("signYear"))){
                    int y = Integer.parseInt((String)sign.get("signYear"));
                    if (y == year) {
                        rs.put("mes", "当前年度已经签约");
                        rs.put("code", "-2");
                        return rs;
                        //如果不等于当前年份,则判断续签表是否有数据
                    } else {
                        return checkRenewData(sqlRenew,rs);
                    }
                } else {
                    rs.put("mes", "签约记录为脏数据");
                    rs.put("code", "0");
                    return rs;
                }
            } else {
                //没有签约记录,不允许续签,提示前往签约
                rs.put("mes", "没有签约记录,请前往签约");
                rs.put("code", "-4");
                return rs;
            }
        } else {
            //如果在签约七月份之后判断是否已经生效,判断是否有旧数据
            List<Map<String,Object>> signFamilys1 = jdbcTemplate.queryForList(signSql);
            if (signFamilys1 != null && signFamilys1.size() > 0) {
                Map<String,Object> map = signFamilys1.get(0);
                int state = (int)map.get("status");
                if(state==1){
                    rs.put("mes", "医生已经同意续签");
                    rs.put("code", "-5");
                }else {
                    rs.put("mes", "当前年度已经签约");
                    rs.put("code", "-2");
                }
                return rs;
            }
            List<Map<String,Object>> signFamilys2 = jdbcTemplate.queryForList(oldSignSql);
            if (signFamilys2 != null && signFamilys2.size() > 0) {
                rs.put("mes", "可以续签(已到期)");
                rs.put("code", "2");
                return rs;
            } else {
                rs.put("mes", "没有签约记录,请前往签约");
                rs.put("code", "-4");
                return rs;
            }
        }
    }

    public JSONObject checkRenewData(String sqlRenew,JSONObject rs){
        List<Map<String,Object>> renews = jdbcTemplate.queryForList(sqlRenew);
        //如果续签表没有数据,则可以续签,有数据提示已经续签
        if (renews != null && renews.size() > 0) {
            Map<String,Object> remew = renews.get(0);
            int state = (int)remew.get("status");
            if(state==1){
                rs.put("mes", "医生已经同意续签");
                rs.put("code", "-5");
            }else{
                rs.put("mes", "已经提交续签");
                rs.put("code", "-3");
            }
            return rs;
        } else {
            rs.put("mes", "可以续签(未到期)");
            rs.put("code", "1");
            return rs;
        }
    }

    /**
     * 根据居民ID查询签约CODE
     *
     * @param patient
     * @return
     */
    public String getSignCodeByPatient(String patient) {

        if (StringUtils.isBlank(patient)) {
            return "";
        }
        try {
            List<SignFamily> signFamilies = jdbcTemplate.queryForList("SELECT * FROM　wlyy_sign_family WHERE t.patient = '" + patient + "' AND t.status >=0 AND t.expenses_status ='1' ", SignFamily.class);
            if (signFamilies != null && signFamilies.size() > 0) {
                return signFamilies.get(0).getCode();
            }
        } catch (Exception e) {
            return "";
        }
        return "";
    }

    /**
     * 获取数据字典
     * @return
     */
    public JSONArray getSigndict(String signYear){
        String sql = null;
        if (StringUtils.isNotBlank(signYear)){
            sql =   " select d.`code`,d.`name` " +
                    " from wlyy_sign_dict d where d.type IN('1','2') AND d.year ='"+signYear+"' AND d.`code` " +
                    " NOT IN(select LEFT(d.code,(INSTR(d.code, '-')-1)) as code from wlyy_sign_dict d WHERE d.code LIKE '%-%' GROUP BY code)";
        }else{
            sql = " select d.`code`,d.`name` " +
                    " from wlyy_sign_dict d where d.type IN('1','2') AND d.year ='"+DateUtil.getSignYear()+"' AND d.`code` " +
                    " NOT IN(select LEFT(d.code,(INSTR(d.code, '-')-1)) as code from wlyy_sign_dict d WHERE d.code LIKE '%-%' GROUP BY code)";
        }


        List<Map<String,Object>> rs = jdbcTemplate.queryForList(sql);
        JSONArray rsJs = new JSONArray(rs);
        return rsJs;
    }

    public JSONArray getSigndictTree(Long teamCodo){

        String sql1 = "SELECT * FROM wlyy_sign_dict t WHERE t.`year` = '"+DateUtil.getSignYear()+"' AND t.`code` NOT LIKE '%-%'";
        String sql2 = "SELECT * FROM wlyy_sign_dict t WHERE t.`year` = '"+DateUtil.getSignYear()+"' AND t.`code` LIKE '%-%'";
        String signServerfousSql = "SELECT COUNT(1) AS fouCount FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCodo+" AND f.`status`>0 AND f.expenses_status ='1' AND f.openid IS NOT NULL AND f.server_type =?";
        String signServerSql = "SELECT COUNT(1) AS total FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCodo+" AND f.`status`>0 AND f.expenses_status ='1' AND f.server_type =?";
        String signSesFousSql = "SELECT COUNT(1) AS fouCount FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCodo+" AND f.`status`>0 AND f.expenses_status ='1' AND f.openid IS NOT NULL AND f.special_population =?";
        String signSesSql ="SELECT COUNT(1) AS total FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCodo+" AND f.`status`>0 AND f.expenses_status ='1'AND f.special_population =?";

        List<Map<String,Object>> rs1 = jdbcTemplate.queryForList(sql1);
        List<Map<String,Object>> rs2 = jdbcTemplate.queryForList(sql2);
        List<ServerLabelTree> tree = new ArrayList<>();
        if(rs1!=null&&rs1.size()>0){
            for(Map<String,Object> map :rs1){
                ServerLabelTree t = new ServerLabelTree();
                String code = (String)map.get("code");
                t.setLabelCode(code);
                t.setLabelName((String)map.get("name"));

                //计算总数
                List<Map<String,Object>> list = jdbcTemplate.queryForList(signServerSql,new Object[]{code});
                //计算关注度
                List<Map<String,Object>> list2 = jdbcTemplate.queryForList(signServerfousSql,new Object[]{code});
                if(list!=null&&list.size()>0){
                    Map<String,Object> cout = list.get(0);
                    t.setAmount((Long)cout.get("total"));
                }else{
                    t.setAmount(0L);
                }
                if(list2!=null&&list2.size()>0){
                    Map<String,Object> cout = list2.get(0);
                    t.setFocusAmount((Long)cout.get("fouCount"));
                }else{
                    t.setFocusAmount(0L);
                }
                List<ServerLabelTree> ch = new ArrayList<>();
                for(Map<String,Object> m :rs2){
                    String c = (String)m.get("code");
                    String[] cc = c.split("-");
                    if(code.equals(cc[0])){
                        ServerLabelTree cht = new ServerLabelTree();
                        cht.setLabelCode(c);
                        cht.setLabelName((String)m.get("name"));
                        //计算总数
                        List<Map<String,Object>> l = jdbcTemplate.queryForList(signSesSql,new Object[]{cc[1]});
                        //计算关注度
                        List<Map<String,Object>> l2 = jdbcTemplate.queryForList(signSesFousSql,new Object[]{cc[1]});
                        if(l!=null&&l.size()>0){
                            Map<String,Object> cout = l.get(0);
                            cht.setAmount((Long)cout.get("total"));
                        }else{
                            cht.setAmount(0L);
                        }
                        if(l2!=null&&l2.size()>0){
                            Map<String,Object> cout = l2.get(0);
                            cht.setFocusAmount((Long)cout.get("fouCount"));
                        }else{
                            cht.setFocusAmount(0L);
                        }
                        ch.add(cht);
                    }
                }
                t.setCh(ch);
                tree.add(t);
            }
        }
       return new JSONArray(tree);
    }

    public String getTeamNameByTeamCode(Long id){
        AdminTeam adminTeam =  doctorAdminTeamDao.findOne(id);
        return adminTeam.getName();
    }

    /**
     * 获取团队分组签约数据
     * @param teamCode
     * @return
     */
    public JSONArray getSignByTeamCodeGpbyServer(Long teamCode){

        // 获取总分组数量
        String totalGSql ="SELECT d.`code` AS serverType,d.`name` AS serverTypeName,ifNULL(c.Amount,0) AS Amount FROM " +
                " wlyy_sign_dict d LEFT JOIN" +
                " ("+
                "SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name AS serverTypeName FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCode+" AND f.`status`>0 AND f.server_type IS NOT NULL GROUP BY f.server_type ORDER BY f.server_type ASC"+
                " ) c ON d.code = c.serverType " +
                " WHERE d.`year`='"+DateUtil.getSignYear()+"' AND d.`code` NOT LIKE '%-%' ORDER BY d.sort ASC";
        List<Map<String,Object>> totalG = jdbcTemplate.queryForList(totalGSql);

        //获取关注量分组数量
        String fousGSql ="SELECT count(1) As focusAmount,f.server_type AS serverType,f.server_type_name AS serverTypeName  FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCode+" AND f.`status`>0  AND f.openid IS NOT NULL AND f.server_type IS NOT NULL GROUP BY f.server_type ";
        List<Map<String,Object>> fousG = jdbcTemplate.queryForList(fousGSql);

        //获取二级节点分组总数
        String sesTotalSql ="SELECT " +
                " LEFT ( " +
                "  d.`code`, " +
                "  INSTR(d.`code`, '-') - 1 " +
                " ) AS serverType, " +
                " substring( " +
                "  d.`code`, " +
                "  INSTR(d.`code`, '-') + 1 " +
                " ) AS specialPopulation, " +
                " d.`name` AS specialPopulationName, " +
                " ifnull(c.Amount, 0) AS Amount " +
                " FROM " +
                " wlyy_sign_dict d " +
                " LEFT JOIN ( "+
                " SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name As serverTypeName ,f.special_population AS specialPopulation,f.special_population_name AS specialPopulationName ," +
                " CONCAT(" +
                " f.server_type," +
                " '-'," +
                " f.special_population" +
                " ) AS dcode "+
                " FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCode+" AND f.`status`>0  AND f.special_population Is NOT NULL AND f.server_type IS NOT NULL GROUP BY f.special_population ORDER BY f.special_population ASC "+
                " ) c ON c.dcode = d.code " +
                " WHERE " +
                " d.`year` = '"+DateUtil.getSignYear()+"'" +
                " AND d.`code` LIKE '%-%' ORDER BY d.sort ASC";
        List<Map<String,Object>> sesTotal = jdbcTemplate.queryForList(sesTotalSql);

        //获取二级节点分组数量
        String sesFousGSql ="SELECT count(1) AS focusAmount,f.server_type  AS serverType,f.server_type_name As serverTypeName,f.special_population  AS specialPopulation,f.special_population_name  AS specialPopulationName FROM wlyy_sign_family f WHERE f.admin_team_code ="+teamCode+" AND f.`status`>0  AND f.special_population Is NOT NULL AND f.openid IS NOT NULL AND f.server_type IS NOT NULL GROUP BY f.special_population ";
        List<Map<String,Object>> sesFousG =jdbcTemplate.queryForList(sesFousGSql);

        List<ServerLabelTree> listTree = new ArrayList<>();

        if(totalG!=null&&totalG.size()>0){
           //得到微信关注量总数层级
            Map<String,Object> fousGMap = new HashMap<>();
            if(fousG!=null&&fousG.size()>0){
                 //将List转换为Map 降低循环层级
                for(Map<String,Object> fg: fousG){
                    String serverType = (String)fg.get("serverType");
                    fousGMap.put(serverType,fg);
                }
            }

            //得到二级总数层级
//            Map<String,Object> sesTotalMap = new HashMap<>();
//            if(sesTotal!=null&&sesTotal.size()>0){
//                //将List转换为Map 降低循环层级
//                for(Map<String,Object> st: sesTotal){
//                    String serverType = (String)st.get("serverType");
//                    sesTotalMap.put(serverType,st);
//                }
//            }

            //得到二级关注度总数层数
            Map<String,Object> sesFousGMap = new HashMap<>();
            if(sesFousG!=null&&sesFousG.size()>0){
                //将List转换为Map 降低循环层级
                for(Map<String,Object> sf: sesFousG){
                    String specialPopulation = (String)sf.get("specialPopulation");
                    sesFousGMap.put(specialPopulation,sf);
                }
            }

            //遍历第一层级总数
            for(Map<String,Object> ttg : totalG){
                //添加第一层级数节点
                ServerLabelTree tree = new ServerLabelTree();
                tree.setAmount((Long)ttg.get("Amount"));

                //设置关注数
                String sevtype = (String)ttg.get("serverType");
                Map<String,Object> st =  (Map<String,Object>)fousGMap.get(sevtype);
                if(st!=null){
                    tree.setFocusAmount((Long)st.get("focusAmount"));
                }else{
                    tree.setFocusAmount(0L);
                }
                tree.setLabelCode((String)ttg.get("serverType"));
                tree.setLabelName((String)ttg.get("serverTypeName"));
                List<ServerLabelTree> ch = new ArrayList<>();
                //遍历节点总数
                if(sesTotal!=null&&sesTotal.size()>0){
                    for(Map<String,Object> sesT:sesTotal){
                        String serType = (String)sesT.get("serverType");
                        if(tree.getLabelCode().equals(serType)){
                            ServerLabelTree chTree = new ServerLabelTree();
                            String specialPopulation = (String)sesT.get("specialPopulation");
                            chTree.setLabelCode(tree.getLabelCode()+"-"+specialPopulation);
                            chTree.setLabelName((String)sesT.get("specialPopulationName"));
                            chTree.setAmount((Long)sesT.get("Amount"));
                            chTree.setParentCode(tree.getLabelCode());
                            Map<String,Object> sFousG = (Map<String,Object>)sesFousGMap.get(specialPopulation);
                            if(sFousG!=null){
                                chTree.setFocusAmount((Long)sFousG.get("focusAmount"));
                            }else{
                                chTree.setFocusAmount(0L);
                            }
                            ch.add(chTree);
                        }
                    }
                }
                tree.setCh(ch);
                listTree.add(tree);
            }
        }
        return new JSONArray(listTree);
    }

    /**
     * 获取医生个人分组签约数据
     * @return
     */
    public JSONArray getSignByDoctorCodeGpbyServer(String doctor,String teamCode){
        String teamCodeSql="";
        if(!org.springframework.util.StringUtils.isEmpty(teamCode)){
            teamCodeSql=" and f.admin_team_code="+teamCode+" ";
        }
        // 获取总分组数量
        String totalGSql ="SELECT d.`code` AS serverType,d.`name` AS serverTypeName,ifNULL(c.Amount,0) AS Amount FROM " +
                " wlyy_sign_dict d LEFT JOIN" +
                " ("+
                " SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name AS serverTypeName FROM wlyy_sign_family f  WHERE  (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"') AND f.`status`>0 AND f.server_type IS NOT NULL "+teamCodeSql+" GROUP BY f.server_type ORDER BY f.server_type ASC"+
                " ) c ON d.code = c.serverType " +
                " WHERE d.`year`='"+DateUtil.getSignYear()+"' AND d.`code` NOT LIKE '%-%' ORDER BY d.sort ASC";

//        String totalGSql = "SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name AS serverTypeName FROM wlyy_sign_family f WHERE (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"') AND f.`status`>0 AND f.server_type IS NOT NULL "+teamCodeSql+" GROUP BY f.server_type ORDER BY f.server_type ASC";
        List<Map<String,Object>> totalG = jdbcTemplate.queryForList(totalGSql);

        //获取关注量分组数量
        String fousGSql ="SELECT count(1) As focusAmount,f.server_type AS serverType,f.server_type_name AS serverTypeName  FROM wlyy_sign_family f ,wlyy_patient p WHERE f.patient =p.code AND   (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"') AND f.`status`>0  AND p.openid IS NOT NULL AND p.openid <>''  "+teamCodeSql+" AND  f.server_type IS NOT NULL GROUP BY f.server_type ";
        List<Map<String,Object>> fousG = jdbcTemplate.queryForList(fousGSql);

        //获取二级节点分组总数
        String sesTotalSql ="SELECT " +
                " LEFT ( " +
                "  d.`code`, " +
                "  INSTR(d.`code`, '-') - 1 " +
                " ) AS serverType, " +
                " substring( " +
                "  d.`code`, " +
                "  INSTR(d.`code`, '-') + 1 " +
                " ) AS specialPopulation, " +
                " d.`name` AS specialPopulationName, " +
                " ifnull(c.Amount, 0) AS Amount " +
                " FROM " +
                " wlyy_sign_dict d " +
                " LEFT JOIN ( "+
                " SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name As serverTypeName ,f.special_population AS specialPopulation,f.special_population_name AS specialPopulationName ," +
                " CONCAT(" +
                " f.server_type," +
                " '-'," +
                " f.special_population" +
                " ) AS dcode FROM wlyy_sign_family f WHERE (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"')  "+teamCodeSql+" AND f.`status`>0  AND f.special_population Is NOT NULL AND f.server_type IS NOT NULL GROUP BY f.special_population ORDER BY f.special_population ASC )" +
                " c ON c.dcode = d.code " +
                " WHERE\n" +
                " d.`year` = '"+DateUtil.getSignYear()+"'" +
                " AND d.`code` LIKE '%-%' ORDER BY d.sort ASC";
        //String sesTotalSql ="SELECT count(1) AS Amount,f.server_type AS serverType,f.server_type_name As serverTypeName ,f.special_population AS specialPopulation,f.special_population_name AS specialPopulationName  FROM wlyy_sign_family f WHERE (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"')  "+teamCodeSql+" AND f.`status`>0  AND f.special_population Is NOT NULL AND f.server_type IS NOT NULL GROUP BY f.special_population ORDER BY f.special_population ASC ";
        List<Map<String,Object>> sesTotal = jdbcTemplate.queryForList(sesTotalSql);

        //获取二级节点分组数量
        String sesFousGSql ="SELECT count(1) AS focusAmount,f.server_type  AS serverType,f.server_type_name As serverTypeName,f.special_population  AS specialPopulation,f.special_population_name  AS specialPopulationName FROM wlyy_sign_family f  ,wlyy_patient p WHERE f.patient =p.code AND  (f.doctor ='"+doctor+"' OR f.doctor_health ='"+doctor+"')  "+teamCodeSql+" AND f.`status`>0  AND f.special_population Is NOT NULL AND p.openid IS NOT NULL AND p.openid <>''  AND f.server_type IS NOT NULL GROUP BY f.special_population ";
        List<Map<String,Object>> sesFousG =jdbcTemplate.queryForList(sesFousGSql);

        List<ServerLabelTree> listTree = new ArrayList<>();

        if(totalG!=null&&totalG.size()>0){
            //得到微信关注量总数层级
            Map<String,Object> fousGMap = new HashMap<>();
            if(fousG!=null&&fousG.size()>0){
                //将List转换为Map 降低循环层级
                for(Map<String,Object> fg: fousG){
                    String serverType = (String)fg.get("serverType");
                    fousGMap.put(serverType,fg);
                }
            }

            //得到二级总数层级
//            Map<String,Object> sesTotalMap = new HashMap<>();
//            if(sesTotal!=null&&sesTotal.size()>0){
//                //将List转换为Map 降低循环层级
//                for(Map<String,Object> st: sesTotal){
//                    String serverType = (String)st.get("serverType");
//                    sesTotalMap.put(serverType,st);
//                }
//            }
            //得到二级关注度总数层数
            Map<String,Object> sesFousGMap = new HashMap<>();
            if(sesFousG!=null&&sesFousG.size()>0){
                //将List转换为Map 降低循环层级
                for(Map<String,Object> sf: sesFousG){
                    String specialPopulation = (String)sf.get("specialPopulation");
                    sesFousGMap.put(specialPopulation,sf);
                }
            }

            //遍历第一层级总数
            for(Map<String,Object> ttg : totalG){
                //添加第一层级数节点
                ServerLabelTree tree = new ServerLabelTree();
                tree.setAmount((Long)ttg.get("Amount"));

                //设置关注数
                String sevtype = (String)ttg.get("serverType");
                Map<String,Object> st =  (Map<String,Object>)fousGMap.get(sevtype);
                if(st!=null){
                    tree.setFocusAmount((Long)st.get("focusAmount"));
                }else{
                    tree.setFocusAmount(0L);
                }
                tree.setLabelCode((String)ttg.get("serverType"));
                tree.setLabelName((String)ttg.get("serverTypeName"));
                List<ServerLabelTree> ch = new ArrayList<>();
                //遍历节点总数
                if(sesTotal!=null&&sesTotal.size()>0){
                    for(Map<String,Object> sesT:sesTotal){
                        String serType = (String)sesT.get("serverType");
                        if(tree.getLabelCode().equals(serType)){
                            ServerLabelTree chTree = new ServerLabelTree();
                            String specialPopulation = (String)sesT.get("specialPopulation");
                            chTree.setLabelCode(tree.getLabelCode()+"-"+specialPopulation);
                            chTree.setLabelName((String)sesT.get("specialPopulationName"));
                            chTree.setAmount((Long)sesT.get("Amount"));
                            chTree.setParentCode(tree.getLabelCode());
                            Map<String,Object> sFousG = (Map<String,Object>)sesFousGMap.get(specialPopulation);
                            if(sFousG!=null){
                                chTree.setFocusAmount((Long)sFousG.get("focusAmount"));
                            }else{
                                chTree.setFocusAmount(0L);
                            }
                            ch.add(chTree);
                        }
                    }
                }
                tree.setCh(ch);
                listTree.add(tree);
            }
        }
        return new JSONArray(listTree);
    }
}
