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

import com.google.common.collect.Lists;
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.SignPatientLabel;
import com.yihu.wlyy.entity.doctor.team.sign.SignPatientLabelInfo;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.PatientDisease;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.logs.BusinessLogs;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.doctor.DoctorPatientGroupInfoDao;
import com.yihu.wlyy.repository.doctor.SignPatientLabelDao;
import com.yihu.wlyy.repository.doctor.SignPatientLabelInfoDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.PatientDiseaseDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.repository.patient.SignFamilyRenewDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.service.app.team.AdminTeamService;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.IdCardUtil;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 患者标签信息服务
 * <p>
 * Created by lyr on 2016/10/9.
 */
@Service
@Transactional
public class SignPatientLabelInfoService extends BaseService {

    @Autowired
    SignPatientLabelService labelService;
    @Autowired
    DoctorDao doctorDao;
    @Autowired
    PatientDao patientDao;
    @Autowired
    SignPatientLabelInfoDao labelInfoDao;
    @Autowired
    PatientDiseaseDao diseaseDao;
    @Autowired
    DoctorPatientGroupInfoDao groupInfoDao;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    SignFamilyDao signFamilyDao;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    AdminTeamService adminTeamService;
    @Autowired
    SignPatientLabelDao labelDao;
    @Autowired
    SignFamilyRenewDao signFamilyRenewDao;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 查询单个居民信息
     *
     * @param patient
     * @return
     * @throws Exception
     */
    public JSONObject getPatient(String patient) throws Exception {
        JSONObject json = new JSONObject();
        Patient p = patientDao.findByCode(patient);

        if (p == null) {
            throw new Exception("patient info can not find");
        }

        // 设置患者标识
        json.put("code", p.getCode());
        // 设置患者姓名
        json.put("name", p.getName());
        // 设置患者手机号
        json.put("mobile", p.getMobile());
        // 设置患者微信openid
        json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
        // 设置患者联系电话
        json.put("phone", p.getPhone());
        // 设置患者头像
        json.put("photo", p.getPhoto());
        // 设置患者年龄
        json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
        // 设置患者性别
        json.put("sex", p.getSex());
        // 身份证号
        json.put("idcard", p.getIdcard());
        // 设置患者居住省份
        json.put("provinceName", p.getProvinceName());
        json.put("cityName", p.getCityName());
        json.put("townName", p.getTownName());
        json.put("streetName", p.getStreetName());
        // 设置患者地址
        json.put("address", p.getAddress());
        // 社保号
        json.put("ssc", p.getSsc());

        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
        SignFamily familySign = signFamilyDao.findSignByPatient(patient, 2);

        if (ssSign != null) {
            // 设置患者紧急联系人
            json.put("emerMobile", StringUtils.isEmpty(ssSign.getEmerMobile()) ? "" : String.valueOf(ssSign.getEmerMobile()));
            // 设置签约日期
            json.put("qyrq", ssSign.getApplyDate() != null ? DateUtil.dateToStr((Date) ssSign.getApplyDate(), DateUtil.YYYY_MM_DD) : "");
            // 设置签约类型
            json.put("signType", 1);
            // 设置签约状态
            json.put("ssStatus", ssSign.getStatus());

            json.put("ssDoctor", ssSign.getDoctor());
            json.put("ssDoctorName", ssSign.getDoctorName());
            json.put("ssDoctorHealth", ssSign.getDoctorHealth());
            json.put("ssDoctorHealthName", ssSign.getDoctorHealthName());
            json.put("ssAdminTeam", ssSign.getAdminTeamId());
            json.put("ssHospital", ssSign.getHospital());
            json.put("ssHospitalName", ssSign.getHospitalName());
            json.put("ssBeginDate", DateUtil.dateToStr(ssSign.getBegin(), DateUtil.YYYY_MM_DD));
            json.put("ssEndDate", DateUtil.dateToStr(ssSign.getEnd(), DateUtil.YYYY_MM_DD));
        }
        if (familySign != null) {
            // 设置患者紧急联系人
            json.put("emerMobile", StringUtils.isEmpty(familySign.getEmerMobile()) ? "" : String.valueOf(familySign.getEmerMobile()));
            // 设置签约日期
            json.put("qyrq", familySign.getApplyDate() != null ? DateUtil.dateToStr((Date) familySign.getApplyDate(), DateUtil.YYYY_MM_DD) : "");
            // 设置签约日期
            json.put("patientApplyDate", familySign.getPatientApplyDate() != null ? DateUtil.dateToStr((Date) familySign.getPatientApplyDate(), DateUtil.YYYY_MM_DD) : "");
            // 设置签约类型
            json.put("signType", json.has("signType") ? 3 : 2);
            // 缴费情况
            json.put("expensesStatus", StringUtils.isNotEmpty(familySign.getExpensesStatus()) ? String.valueOf(familySign.getExpensesStatus()) : "0");
            // 缴费时间
            json.put("expensesTime", familySign.getExpensesTime() != null ? DateUtil.dateToStr((Date) familySign.getExpensesTime(), DateUtil.YYYY_MM_DD_HH_MM) : "");
            // 缴费类型
            json.put("expensesType", StringUtils.isNotEmpty(familySign.getExpensesType()) ? String.valueOf(familySign.getExpensesType()) : "");
            // 设置签约状态
            json.put("familyStatus", familySign.getStatus());
            json.put("jtBeginDate", DateUtil.dateToStr(familySign.getBegin(), DateUtil.YYYY_MM_DD));
            json.put("jtEndDate", DateUtil.dateToStr(familySign.getEnd(), DateUtil.YYYY_MM_DD));

            json.put("jtDoctor", familySign.getDoctor());
            json.put("jtDoctorName", familySign.getDoctorName());
            json.put("jtDoctorHealth", familySign.getDoctorHealth());
            json.put("jtDoctorHealthName", familySign.getDoctorHealthName());
            json.put("jtAdminTeam", familySign.getAdminTeamId());
            json.put("jtHospital", familySign.getHospital());
            json.put("jtHospitalName", familySign.getHospitalName());
            if(StringUtils.isNotBlank(familySign.getSpecialPopulation())){
                json.put("jtServerName", familySign.getSpecialPopulationName()==null?"":familySign.getSpecialPopulationName());
                json.put("jtServer", familySign.getSpecialPopulation()==null?"":familySign.getServerType()+"-"+familySign.getSpecialPopulation());
            }else{
                json.put("jtServerName", familySign.getServerTypeName()==null?"":familySign.getServerTypeName());
                json.put("jtServer", familySign.getServerType()==null?"":familySign.getServerType());
            }


            if ("1".equals(familySign.getExpensesStatus())) {
                json.put("qyrq", familySign.getExpensesTime() != null ? DateUtil.dateToStr((Date) familySign.getExpensesTime(), DateUtil.YYYY_MM_DD) : "");
            }
        }

        if (json.has("expensesStatus") && (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0"))) {
            boolean epTime = false;
            try {
                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!epTime) {
                json.put("expensesRemindStatus", 0);
            } else {
                json.put("expensesRemindStatus", 1);
            }
        }

        boolean epTime = false;
        try {
            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!epTime) {
            json.put("wechatFocusRemind", 0);
        } else {
            json.put("wechatFocusRemind", 1);
        }

        String timeKey = DateUtil.dateToStr(new Date(), "yyyyMMdd");
        String flag = redisTemplate.opsForValue().get("renew:" + timeKey + ":" + patient);
        if (StringUtils.isNotBlank(flag)) {
            json.put("isRemindRenew", "1");
        } else {
            json.put("isRemindRenew", "0");
        }
        String sql = "SELECT t.czrq FROM wlyy_sign_family_renew t WHERE t.status>=0 AND t.is_valid =0";
        List<Map<String, Object>> renews = jdbcTemplate.queryForList(sql);
        if (renews != null && renews.size() > 0) {
            Map<String, Object> renew = renews.get(0);
            json.put("renewTime", renew.get("czrq"));
        }

        return json;
    }

    /**
     * 根据标签查询患者信息
     *
     * @param labelCode 标签code
     * @param labelType 标签类型
     * @param page      第几页
     * @param pagesize  页大小
     * @return
     */
    public JSONArray getPatientByLabel(String doctor, String labelCode, String labelType, Long teamCode, int page, int pagesize) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        Map<String, JSONObject> result = new TreeMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        int start = page * pagesize;
        String sql = "";
        Object[] args = null;

        if (labelType.equals("5")) {
            Calendar today = Calendar.getInstance();
            Calendar startDate = Calendar.getInstance();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            sql = "select * " +
                    " from " +
                    "     wlyy_sign_family " +
                    " where (doctor = ? or doctor_health = ?) and status > 0 and admin_team_code = ? ";

            if (labelCode.equals("1")) {
                int week = today.get(Calendar.DAY_OF_WEEK) - 2;

                if (week == -1) {
                    week = 6;
                }
                startDate.add(Calendar.DATE, -week);
                sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
            } else if (labelCode.equals("2")) {
                startDate.set(Calendar.DATE, 1);
                sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
            } else if (labelCode.equals("3")) {
                startDate.add(Calendar.DATE, 30);
                sql += " and end between '" + (df.format(today.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(startDate.getTime()) + " 23:59:59'");
            } else {
                throw new Exception("label is not exist");
            }
            sql += " order by openid desc,convert(name using gbk) ";
            args = new Object[]{doctor, doctor, teamCode};
        }else if("1".equals(labelType)){
            int flag =   labelCode.indexOf("-");
            if(flag!=-1){
                String label[] = labelCode.split("-");
                sql = "SELECT " +
                        " t1.* " +
                        " p.openid " +
                        " FROM " +
                        "    wlyy_sign_family t1 ,wlyy_patient p" +
                        " WHERE p.code = t1.patient " +
                        "    AND (t1.doctor = ? or t1.doctor_health = ?) " +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? AND  t1.special_population = '"+label[1]+"' ORDER BY p.openid DESC ";
                args = new Object[]{doctor, doctor, teamCode};
            }else{
                sql = "SELECT " +
                        "    t1.* "+
                        " FROM " +
                        "    wlyy_sign_family t1 ,wlyy_patient p " +
                        " WHERE  p.code = t1.patient " +
                        "    AND (t1.doctor = ? or t1.doctor_health = ?) " +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? AND  t1.server_type = '"+labelCode+"'  ORDER BY p.openid DESC ";
                args = new Object[]{doctor, doctor, teamCode};
            }
        } else {
            if (labelCode.equals("0")) {
                sql = "SELECT " +
                        "    t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1 " +
                        " left join " +
                        "    (select l.patient,l.label,l.label_type,l.label_name from wlyy_sign_family f left join wlyy_sign_patient_label_info l on f.patient = l.patient where (f.doctor = '" + doctor + "' or f.doctor_health = '" + doctor + "') and f.status > 0 and l.label_type = ? and l.status = 1) t2 " +
                        " on t1.patient = t2.patient " +
                        " WHERE " +
                        "    t2.patient is null " +
                        "    AND (t1.doctor = ? or t1.doctor_health = ?) " +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? order by t1.openid desc,convert(t1.name using gbk) ";

                args = new Object[]{labelType, doctor, doctor, teamCode};
            }else {
                sql = "SELECT " +
                        "    t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1, " +
                        "    wlyy_sign_patient_label_info t2 " +
                        " WHERE " +
                        "    t2.label = ? " +
                        "    AND t2.label_type = ? " +
                        "    AND t2.status = 1 " +
                        "    AND t1.patient = t2.patient " +
                        "    AND (t1.doctor = ? or t1.doctor_health = ?)" +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? order by t1.openid desc,convert(t1.name using gbk) ";

                args = new Object[]{labelCode, labelType, doctor, doctor, teamCode};
            }
        }

        sql += " limit " + start + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                //List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                //json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        if (result.size() > 0) {
            List<JSONObject> list = Lists.newArrayList(result.values());

            Collections.sort(list, new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    String openid1 = o1.has("openid") ? o1.getString("openid") : "";
                    String openid2 = o2.has("openid") ? o2.getString("openid") : "";
                    int re = openid1.compareTo(openid2);
                    if (re > 0) {
                        return -1;
                    } else if (re < 0) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });

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

    /**
     * 获取团队下的患者
     *
     * @param doctor
     * @param teamCode
     * @param page
     * @param pagesize
     * @return
     * @throws Exception
     */
    public JSONArray getPatientByTeamCode(String doctor, long teamCode, String exLabelCode, String exLabelType, int page, int pagesize) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        int start = page * pagesize;
        String sql = "";
        Object[] args = new Object[]{doctor, doctor, teamCode};

        sql = " select * from wlyy_sign_family where " +
                " (doctor = ? or doctor_health = ?) and status > 0 and admin_team_code = ? limit " + start + "," + pagesize;

        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }
                    continue;
                }

                if (StringUtils.isNotEmpty(exLabelCode)) {
                    SignPatientLabelInfo labelInfoEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(p.getCode(), exLabelCode, exLabelType, 1);

                    if (labelInfoEx != null) {
                        continue;
                    }
                } else if (StringUtils.isNotEmpty(exLabelType)) {
                    List<SignPatientLabelInfo> labelExs = labelInfoDao.findByPatientAndLabelTypeAndStatus(p.getCode(), exLabelType, 1);

                    if (labelExs != null && labelExs.size() > 0) {
                        continue;
                    }
                }

                List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }

    /**
     * 查询某个标签类型的所有标签居民数统计
     *
     * @param labelType 标签类型
     * @param teamCode  标签类型为4时,不能为空
     * @return
     */
    public JSONArray getPatientAmountByLabelType(String doctor, String labelType, Long teamCode) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        List<SignPatientLabel> labels = labelService.getLabelsByTypeAndTeam(labelType, teamCode.toString());
        JSONArray result = new JSONArray();

        SignPatientLabel labelNo = new SignPatientLabel();

        if (!labelType.equals("5")) {
            labelNo.setLabelCode("0");
            labelNo.setLabelName(labelType.equals("1") ? "未分组" : "未标注");
            labelNo.setStatus(1);
            labelNo.setIsSystem(1);
            labelNo.setLabelType(labelType);
            labelNo.setSort(999999999);

            labels.add(labelNo);
        }

        if (labels != null) {
            for (SignPatientLabel label : labels) {
                JSONObject json = new JSONObject();

                json.put("labelCode", label.getLabelCode());
                json.put("labelName", label.getLabelName());
                json.put("isSystem", label.getIsSystem());

                int amount = 0;
                String sql = "";
                Object[] args = null;

                if (labelType.equals("5")) {
                    Calendar today = Calendar.getInstance();
                    Calendar startDate = Calendar.getInstance();
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                    sql = "select count(DISTINCT patient) count" +
                            " from " +
                            "     wlyy_sign_family " +
                            " where (doctor = ? or doctor_health = ?) and status > 0 " +
                            (teamCode > 0 ? " and admin_team_code = ? " : "");

                    if (label.getLabelCode().equals("1")) {
                        int week = today.get(Calendar.DAY_OF_WEEK) - 2;
                        if (week == -1) {
                            week = 6;
                        }
                        startDate.add(Calendar.DATE, -week);
                        sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
                    } else if (label.getLabelCode().equals("2")) {
                        startDate.set(Calendar.DATE, 1);
                        sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
                    } else if (label.getLabelCode().equals("3")) {
                        startDate.add(Calendar.DATE, 30);
                        sql += " and end between '" + (df.format(today.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(startDate.getTime()) + " 23:59:59'");
                    } else {
                        throw new Exception("label is not exist");
                    }
                    if (teamCode > 0) {
                        args = new Object[]{doctor, doctor, teamCode};
                    } else {
                        args = new Object[]{doctor, doctor};
                    }
                } else {
                    if (label.getLabelCode().equals("0")) {
                        sql = " SELECT " +
                                "     count(DISTINCT t1.patient) count" +
                                " FROM" +
                                "     wlyy_sign_family t1 " +
                                " left join " +
                                "    (select l.patient,l.label,l.label_type,l.label_name from wlyy_sign_family f left join wlyy_sign_patient_label_info l on f.patient = l.patient where (f.doctor = '" + doctor + "' or f.doctor_health = '" + doctor + "') and f.status > 0 and l.label_type = ? and l.status = 1) t2 " +
                                " on t1.patient = t2.patient " +
                                " WHERE" +
                                "     t2.patient is null " +
                                "     AND (t1.doctor = ? or t1.doctor_health = ?)" +
                                "     AND t1.status > 0 " +
                                (teamCode > 0 ? "    AND t1.admin_team_code = ? " : "");

                        if (teamCode > 0) {
                            args = new Object[]{labelType, doctor, doctor, teamCode};
                        } else {
                            args = new Object[]{labelType, doctor, doctor};
                        }
                    } else {
                        sql = " SELECT " +
                                "     count(DISTINCT t1.patient) count" +
                                " FROM" +
                                "     wlyy_sign_family t1, " +
                                "     wlyy_sign_patient_label_info t2 " +
                                " WHERE" +
                                "     t1.patient = t2.patient " +
                                "     AND t2.label = ? " +
                                "     AND t2.label_type = ? " +
                                "     AND t2.status = 1 " +
                                "     AND (t1.doctor = ? or t1.doctor_health = ?)" +
                                "     AND t1.status > 0 " +
                                (teamCode > 0 ? "    AND t1.admin_team_code = ? " : "");

                        if (teamCode > 0) {
                            args = new Object[]{label.getLabelCode(), labelType, doctor, doctor, teamCode};
                        } else {
                            args = new Object[]{label.getLabelCode(), labelType, doctor, doctor};
                        }
                    }
                }

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

                if (count != null && count.size() > 0 && count.get(0).containsKey("count")) {
                    amount = Integer.valueOf(String.valueOf(count.get(0).get("count")));
                }

                json.put("amount", amount);

                int focusAmount = 0;
                sql += labelType.equals("5") ? " AND LENGTH(TRIM(IFNULL(openid,''))) > 0 " : " AND LENGTH(TRIM(IFNULL(t1.openid,''))) > 0 ";
                List<Map<String, Object>> focusCount = jdbcTemplate.queryForList(sql, args);

                if (focusCount != null && focusCount.size() > 0 && focusCount.get(0).containsKey("count")) {
                    focusAmount = Integer.valueOf(String.valueOf(focusCount.get(0).get("count")));
                }

                json.put("focusAmount", focusAmount);

                if (label.getLabelCode().equals("0") && labelType.equals("1") && amount < 1) {
                    continue;
                }
                result.put(json);
            }
        }

        return result;
    }

    /**
     * 获取团队签约人数
     *
     * @param teamCode
     * @return
     * @throws Exception
     */
    public int getPatientAmountByTeam(Long teamCode) throws Exception {
        int count = signFamilyDao.findByAdminTeamIdAndStatus(teamCode, 1);
        return count;
    }

    /**
     * 获取团队签约人数
     *
     * @param teamCode
     * @return
     * @throws Exception
     */
    public int getPatientFocusAmountByTeam(Long teamCode) throws Exception {
        String sql = "select count(distinct patient) count from wlyy_sign_family where admin_team_code = ? and status > 0 and length(trim(ifnull(openid,''))) > 1";
        List<Map<String, Object>> count = jdbcTemplate.queryForList(sql, new Object[]{teamCode});
        if (count != null && count.size() > 0 && count.get(0).containsKey("count")) {
            return Integer.valueOf(String.valueOf(count.get(0).get("count")));
        } else {
            return 0;
        }
    }

    /**
     * 查询某个标签类型的所有标签居民数统计,或者所有类型
     *
     * @param labelType 标签类型
     * @param teamCode  标签类型为4时,不能为空
     * @return
     */
    public JSONArray getPatientAmountByTeamGroupLable(Long teamCode, String labelType) throws Exception {
        Boolean isAll = false;
        List<SignPatientLabel> labels = new ArrayList<>();
        if ("0".equals(labelType)) {
            labels = labelService.getTeamAllLabels(teamCode);
            isAll = true;
        } else {
            labels = labelService.getLabelsByTypeAndTeam(labelType, teamCode.toString());
        }
        JSONArray result = new JSONArray();

        SignPatientLabel labelNo = new SignPatientLabel();

        if (!labelType.equals("5")) {
            labelNo.setLabelCode("0");
            labelNo.setLabelName(labelType.equals("1") ? "未分组" : "未标注");
            labelNo.setStatus(1);
            labelNo.setIsSystem(1);
            labelNo.setLabelType(labelType);
            labelNo.setSort(999999999);

            labels.add(labelNo);
        }

        if (labels != null) {
            for (SignPatientLabel label : labels) {
                if (isAll) {//查询所有
                    labelType = label.getLabelType();
                }
                JSONObject json = new JSONObject();

                json.put("labelCode", label.getLabelCode());
                json.put("labelName", label.getLabelName());
                json.put("isSystem", label.getIsSystem());

                int amount = 0;
                String sql = "";
                Object[] args = null;

                if (labelType.equals("5")) {
                    Calendar today = Calendar.getInstance();
                    Calendar startDate = Calendar.getInstance();
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                    sql = "select count(DISTINCT  patient) count" +
                            " from " +
                            "     wlyy_sign_family " +
                            " where status > 0 " +
                            " and admin_team_code = ? ";

                    if (label.getLabelCode().equals("1")) {
                        int week = today.get(Calendar.DAY_OF_WEEK) - 2;
                        if (week == -1) {
                            week = 6;
                        }
                        startDate.add(Calendar.DATE, -week);
                        sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
                    } else if (label.getLabelCode().equals("2")) {
                        startDate.set(Calendar.DATE, 1);
                        sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
                    } else if (label.getLabelCode().equals("3")) {
                        startDate.add(Calendar.DATE, 30);
                        sql += " and end between '" + (df.format(today.getTime()) + " 00:00:00")
                                + "' and '" + (df.format(startDate.getTime()) + " 23:59:59'");
                    } else {
                        throw new Exception("label is not exist");
                    }

                    args = new Object[]{teamCode};
                } else {
                    if (label.getLabelCode().equals("0")) {
                        sql = " SELECT " +
                                "     count(DISTINCT t1.patient) count" +
                                " FROM" +
                                "     wlyy_sign_family t1 " +
                                " left join " +
                                "    (select repl.patient,repl.label,repl.label_type,repl.label_name from wlyy_sign_family repf left join wlyy_sign_patient_label_info repl on repf.patient = repl.patient where repf.admin_team_code = ? and repf.status > 0 and repl.label_type = ? and repl.status = 1) t2 " +
                                " on t1.patient = t2.patient " +
                                " WHERE" +
                                "     t2.patient is null " +
                                "     AND t1.status > 0 " +
                                "     AND t1.admin_team_code = ? ";

                        args = new Object[]{teamCode, labelType, teamCode};
                    } else {
                        sql = " SELECT " +
                                "     count(DISTINCT t1.patient) count" +
                                " FROM" +
                                "     wlyy_sign_family t1, " +
                                "     wlyy_sign_patient_label_info t2 " +
                                " WHERE" +
                                "     t1.patient = t2.patient " +
                                "     AND t2.label = ? " +
                                "     AND t2.label_type = ? " +
                                "     AND t2.status = 1 " +
                                "     AND t1.status > 0 " +
                                "    AND t1.admin_team_code = ? ";

                        args = new Object[]{label.getLabelCode(), labelType, teamCode};
                    }
                }

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

                if (count != null && count.size() > 0 && count.get(0).containsKey("count")) {
                    amount = Integer.valueOf(String.valueOf(count.get(0).get("count")));
                }

                json.put("amount", amount);

                int focusAmount = 0;
                sql += labelType.equals("5") ? " AND LENGTH(TRIM(IFNULL(openid,''))) > 0 " : " AND LENGTH(TRIM(IFNULL(t1.openid,''))) > 0 ";
                List<Map<String, Object>> focusCount = jdbcTemplate.queryForList(sql, args);

                if (focusCount != null && focusCount.size() > 0 && focusCount.get(0).containsKey("count")) {
                    focusAmount = Integer.valueOf(String.valueOf(focusCount.get(0).get("count")));
                }

                json.put("focusAmount", focusAmount);

                if (label.getLabelCode().equals("0") && labelType.equals("1") && amount < 1) {
                    continue;
                }
                result.put(json);
            }
        }
        return result;
    }


    /**
     * 续签设置标签v1.3.3.2
     * 设置患者标签
     *
     * @param patient     患者名称
     * @param health      健康情况标签
     * @param disease     疾病类型标签
     * @param custom      自定义标签
     * @return
     */
    public int setRenewPatientLabels(String patient, String health, String disease, String custom, String doctor, String caller) {
        Patient p = patientDao.findByCode(patient);
        String idcard;
        String patientName;
        if (p == null) {
            return 0;
        } else {

            idcard = p.getIdcard();
            patientName = p.getName();
            List<PatientDisease> diseaseSs = diseaseDao.findByPatientSsDisease(p.getCode());

            if (diseaseSs != null && diseaseSs.size() > 0) {
                String[] diseaseArr = disease.split(",");

                if (diseaseArr == null || diseaseArr.length < 1) {
                    return -3;
                }

                for (PatientDisease dis : diseaseSs) {
                    if (!Arrays.asList(diseaseArr).contains(dis.getDisease())) {
                        return -3;
                    }
                }
            }
        }

        JSONArray logArray = new JSONArray();
        JSONArray teams = adminTeamService.findRenewPatientDoctorTeam(patient, doctor);
        List<String> teamCodes = new ArrayList<>();

        if (teams.length() > 0) {
            for (int i = 0; i < teams.length(); i++) {
                teamCodes.add(String.valueOf(teams.getJSONObject(i).getLong("id")));
            }
        } else {
            return -4;
        }

        String[] diseaseArr = disease.split(",");
        String[] customArr = custom.split(",");

        if (StringUtils.isNotEmpty(health)) {
            SignPatientLabelInfo healthEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, health, "2", 1);

            if (healthEx == null) {
                // 健康情况标签
                int healthAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "2", 1);

                SignPatientLabelInfo healthLabel = new SignPatientLabelInfo();
                SignPatientLabel label = labelService.getLabelByCodeAndType(health, "2");

                if (label == null) {
                    return -1;
                }

                healthLabel.setPatient(patient);
                healthLabel.setPname(patientName);
                healthLabel.setLabelType("2");
                healthLabel.setLabel(health);
                healthLabel.setLabelName(label.getLabelName());
                healthLabel.setStatus(1);
                healthLabel.setCzrq(new Date());

                labelInfoDao.save(healthLabel);
                logArray.put(new JSONObject(label));
            }
        } else {
            return -2;
        }

        if (diseaseArr != null && diseaseArr.length > 0) {
            List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, "3", 1);
            Map<String, SignPatientLabelInfo> labelMap = new HashMap<>();
            List<String> disList = Arrays.asList(diseaseArr);

            for (SignPatientLabelInfo label : labels) {
                labelMap.put(label.getLabel(), label);

                if (!disList.contains(label.getLabel())) {
                    label.setStatus(0);
                    labelInfoDao.save(label);
                }
            }

            for (String diseaseLabel : diseaseArr) {
                if (StringUtils.isEmpty(diseaseLabel)) {
                    continue;
                }

                SignPatientLabelInfo diseaseEx = labelMap.get(diseaseLabel);

                if (diseaseEx == null) {
                    SignPatientLabelInfo disLabel = new SignPatientLabelInfo();
                    SignPatientLabel label = labelService.getLabelByCodeAndType(diseaseLabel, "3");

                    if (label == null) {
                        return -1;
                    }

                    disLabel.setPatient(patient);
                    disLabel.setPname(patientName);
                    disLabel.setLabelType("3");
                    disLabel.setLabel(diseaseLabel);
                    disLabel.setLabelName(label.getLabelName());
                    disLabel.setStatus(1);
                    disLabel.setCzrq(new Date());

                    labelInfoDao.save(disLabel);
                    logArray.put(new JSONObject(label));
                }
            }
        } else {
            // 疾病类型标签
            int disAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "3", 1);
        }

        List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, "4", 1);
        Map<String, SignPatientLabelInfo> labelMap = new HashMap<>();
        List<String> custList = Arrays.asList(customArr);

        for (SignPatientLabelInfo label : labels) {
            labelMap.put(label.getLabel(), label);
            SignPatientLabel lb = labelService.getLabelByCodeAndType(label.getLabel(), "4");
            if(lb!=null) {
                if (!custList.contains(label.getLabel())) {
                    if (lb.getLabelCode().equals("1") || lb.getLabelCode().equals("2") || teamCodes.contains(String.valueOf(lb.getTeamCode()))) {
                        label.setStatus(0);
                        labelInfoDao.save(label);
                    }
                }
            }


        }

        if (customArr != null && customArr.length > 0) {
            for (String customLabel : customArr) {
                if (StringUtils.isEmpty(customLabel)) {
                    continue;
                }
                SignPatientLabelInfo customEx = labelMap.get(customLabel);

                if (customEx == null) {
                    SignPatientLabelInfo cusLabel = new SignPatientLabelInfo();
                    SignPatientLabel label = labelService.getLabelByCodeAndType(customLabel, "4");

                    if (label == null) {
                        return -1;
                    }

                    cusLabel.setPatient(patient);
                    cusLabel.setPname(patientName);
                    cusLabel.setLabelType("4");
                    cusLabel.setLabel(customLabel);
                    cusLabel.setLabelName(label.getLabelName());
                    cusLabel.setStatus(1);
                    cusLabel.setCzrq(new Date());

                    labelInfoDao.save(cusLabel);
                    logArray.put(new JSONObject(label));
                }
            }
        }

        if (diseaseArr != null && diseaseArr.length > 0 && (Arrays.asList(diseaseArr).contains("1")
                || Arrays.asList(diseaseArr).contains("2"))) {
            SignPatientLabelInfo mbEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, "2", "1", 1);

            if (mbEx == null) {
                // 卫计委三大分组
                int wjwAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "1", 1);
                SignPatientLabelInfo disLabel = new SignPatientLabelInfo();

                disLabel.setPatient(patient);
                disLabel.setPname(patientName);
                disLabel.setLabelType("1");
                disLabel.setLabel("2");
                disLabel.setLabelName("慢病人群");
                disLabel.setStatus(1);
                disLabel.setCzrq(new Date());

                labelInfoDao.save(disLabel);
                logArray.put(new JSONObject("{\"labelCode\":\"1\",\"labelName\":\"慢病人群\",\"labelType\":\"1\"}"));
            }
        } else {
            int age = IdCardUtil.getAgeForIdcard(idcard);
            String lbCode = "", lbName = "";
            if (age >= 65) {
                lbCode = "3";
                lbName = "65岁以上人群";
            } else {
                lbCode = "1";
                lbName = "普通人群";
            }

            SignPatientLabelInfo wjwEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, lbCode, "1", 1);

            if (wjwEx == null) {
                // 卫计委三大分组
                int wjwAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "1", 1);
                SignPatientLabelInfo disLabel = new SignPatientLabelInfo();

                disLabel.setPatient(patient);
                disLabel.setPname(patientName);
                disLabel.setLabelType("1");
                disLabel.setStatus(1);
                disLabel.setCzrq(new Date());
                disLabel.setLabel(lbCode);
                disLabel.setLabelName(lbName);

                labelInfoDao.save(disLabel);
                logArray.put(new JSONObject("{\"labelCode\":\"" + lbCode + "\",\"labelName\":\"" + lbName + "\",\"labelType\":\"1\"}"));
            }
        }

        BusinessLogs.info(BusinessLogs.BusinessType.label, caller, patient, logArray);

        return 1;
    }

    /**
     * 设置患者标签
     *
     * @param patient     患者名称
     * @param idcard      身份证号
     * @param patientName 患者姓名
     * @param health      健康情况标签
     * @param disease     疾病类型标签
     * @param custom      自定义标签
     * @return
     */
    public int setPatientLabels(String patient, String idcard, String patientName, String health, String disease, String custom, String doctor, String caller) {
        Patient p = patientDao.findByCode(patient);

        if (p == null && (StringUtils.isEmpty(idcard) || StringUtils.isEmpty(patientName))) {
            return 0;
        } else {
            idcard = p.getIdcard();
            patientName = p.getName();

            List<PatientDisease> diseaseSs = diseaseDao.findByPatientSsDisease(p.getCode());

            if (diseaseSs != null && diseaseSs.size() > 0) {
                String[] diseaseArr = disease.split(",");

                if (diseaseArr == null || diseaseArr.length < 1) {
                    return -3;
                }

                for (PatientDisease dis : diseaseSs) {
                    if (!Arrays.asList(diseaseArr).contains(dis.getDisease())) {
                        return -3;
                    }
                }
            }
        }

        JSONArray logArray = new JSONArray();
        JSONArray teams = adminTeamService.findPatientDoctorTeam(patient, doctor);
        List<String> teamCodes = new ArrayList<>();

        if (teams.length() > 0) {
            for (int i = 0; i < teams.length(); i++) {
                teamCodes.add(String.valueOf(teams.getJSONObject(i).getLong("id")));
            }
        } else {
            return -4;
        }

        String[] diseaseArr = disease.split(",");
        String[] customArr = custom.split(",");

        if (StringUtils.isNotEmpty(health)) {
            SignPatientLabelInfo healthEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, health, "2", 1);

            if (healthEx == null) {
                // 健康情况标签
                int healthAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "2", 1);

                SignPatientLabelInfo healthLabel = new SignPatientLabelInfo();
                SignPatientLabel label = labelService.getLabelByCodeAndType(health, "2");

                if (label == null) {
                    return -1;
                }

                healthLabel.setPatient(patient);
                healthLabel.setPname(patientName);
                healthLabel.setLabelType("2");
                healthLabel.setLabel(health);
                healthLabel.setLabelName(label.getLabelName());
                healthLabel.setStatus(1);
                healthLabel.setCzrq(new Date());

                labelInfoDao.save(healthLabel);
                logArray.put(new JSONObject(label));
            }
        } else {
            return -2;
        }

        if (diseaseArr != null && diseaseArr.length > 0) {
            List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, "3", 1);
            Map<String, SignPatientLabelInfo> labelMap = new HashMap<>();
            List<String> disList = Arrays.asList(diseaseArr);

            for (SignPatientLabelInfo label : labels) {
                labelMap.put(label.getLabel(), label);

                if (!disList.contains(label.getLabel())) {
                    label.setStatus(0);
                    labelInfoDao.save(label);
                }
            }

            for (String diseaseLabel : diseaseArr) {
                if (StringUtils.isEmpty(diseaseLabel)) {
                    continue;
                }

                SignPatientLabelInfo diseaseEx = labelMap.get(diseaseLabel);

                if (diseaseEx == null) {
                    SignPatientLabelInfo disLabel = new SignPatientLabelInfo();
                    SignPatientLabel label = labelService.getLabelByCodeAndType(diseaseLabel, "3");

                    if (label == null) {
                        return -1;
                    }

                    disLabel.setPatient(patient);
                    disLabel.setPname(patientName);
                    disLabel.setLabelType("3");
                    disLabel.setLabel(diseaseLabel);
                    disLabel.setLabelName(label.getLabelName());
                    disLabel.setStatus(1);
                    disLabel.setCzrq(new Date());

                    labelInfoDao.save(disLabel);
                    logArray.put(new JSONObject(label));
                }
            }
        } else {
            // 疾病类型标签
            int disAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "3", 1);
        }

        List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, "4", 1);
        Map<String, SignPatientLabelInfo> labelMap = new HashMap<>();
        List<String> custList = Arrays.asList(customArr);

        for (SignPatientLabelInfo label : labels) {
            labelMap.put(label.getLabel(), label);
            SignPatientLabel lb = labelService.getLabelByCodeAndType(label.getLabel(), "4");
            if(lb!=null){
                if (!custList.contains(label.getLabel())) {
                    if (lb.getLabelCode().equals("1") || lb.getLabelCode().equals("2") || teamCodes.contains(String.valueOf(lb.getTeamCode()))) {
                        label.setStatus(0);
                        labelInfoDao.save(label);
                    }
                }
            }
        }

        if (customArr != null && customArr.length > 0) {
            for (String customLabel : customArr) {
                if (StringUtils.isEmpty(customLabel)) {
                    continue;
                }
                SignPatientLabelInfo customEx = labelMap.get(customLabel);

                if (customEx == null) {
                    SignPatientLabelInfo cusLabel = new SignPatientLabelInfo();
                    SignPatientLabel label = labelService.getLabelByCodeAndType(customLabel, "4");

                    if (label == null) {
                        return -1;
                    }

                    cusLabel.setPatient(patient);
                    cusLabel.setPname(patientName);
                    cusLabel.setLabelType("4");
                    cusLabel.setLabel(customLabel);
                    cusLabel.setLabelName(label.getLabelName());
                    cusLabel.setStatus(1);
                    cusLabel.setCzrq(new Date());

                    labelInfoDao.save(cusLabel);
                    logArray.put(new JSONObject(label));
                }
            }
        }

        if (diseaseArr != null && diseaseArr.length > 0 && (Arrays.asList(diseaseArr).contains("1")
                || Arrays.asList(diseaseArr).contains("2"))) {
            SignPatientLabelInfo mbEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, "2", "1", 1);

            if (mbEx == null) {
                // 卫计委三大分组
                int wjwAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "1", 1);
                SignPatientLabelInfo disLabel = new SignPatientLabelInfo();

                disLabel.setPatient(patient);
                disLabel.setPname(patientName);
                disLabel.setLabelType("1");
                disLabel.setLabel("2");
                disLabel.setLabelName("慢病人群");
                disLabel.setStatus(1);
                disLabel.setCzrq(new Date());

                labelInfoDao.save(disLabel);
                logArray.put(new JSONObject("{\"labelCode\":\"1\",\"labelName\":\"慢病人群\",\"labelType\":\"1\"}"));
            }
        } else {
            int age = IdCardUtil.getAgeForIdcard(idcard);
            String lbCode = "", lbName = "";
            if (age >= 65) {
                lbCode = "3";
                lbName = "65岁以上人群";
            } else {
                lbCode = "1";
                lbName = "普通人群";
            }

            SignPatientLabelInfo wjwEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, lbCode, "1", 1);

            if (wjwEx == null) {
                // 卫计委三大分组
                int wjwAmount = labelInfoDao.deleteByPatientAndLabelTypeAndStatus(patient, "1", 1);
                SignPatientLabelInfo disLabel = new SignPatientLabelInfo();

                disLabel.setPatient(patient);
                disLabel.setPname(patientName);
                disLabel.setLabelType("1");
                disLabel.setStatus(1);
                disLabel.setCzrq(new Date());
                disLabel.setLabel(lbCode);
                disLabel.setLabelName(lbName);

                labelInfoDao.save(disLabel);
                logArray.put(new JSONObject("{\"labelCode\":\"" + lbCode + "\",\"labelName\":\"" + lbName + "\",\"labelType\":\"1\"}"));
            }
        }

        BusinessLogs.info(BusinessLogs.BusinessType.label, caller, patient, logArray);

        return 1;
    }

    /**
     * 查询某个患者的某个类型的标签
     *
     * @param patient   患者code
     * @param labelType 标签类型
     * @return
     */
    public List<SignPatientLabelInfo> getPatientLabelByLabelType(String patient, String labelType) {
        List<SignPatientLabelInfo> labels = new ArrayList<>();

        if (StringUtils.isEmpty(labelType)) {
            labels = labelInfoDao.findByPatientAndStatus(patient, 1);
        } else {
            labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, labelType, 1);
        }

        return labels;
    }

    /**
     * 查询某个患者的某个类型的标签
     *
     * @param patient   患者code
     * @param labelType 标签类型
     * @return
     */
    public JSONArray getPatientLabelByLabelTypeAndTeamCode(String patient, String labelType, long teamCode, String doctor) {
        List<SignPatientLabelInfo> labels = new ArrayList<>();
        JSONArray result = new JSONArray();

        if (StringUtils.isEmpty(labelType)) {
            labels = labelInfoDao.findByPatientAndStatus(patient, 1);
        } else {
            labels = labelInfoDao.findByPatientAndLabelTypeAndStatus(patient, labelType, 1);
        }

        // 查询居民签约团队
        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
        SignFamily jtSign = signFamilyDao.findSignByPatient(patient, 2);
        long ssTeam = 0L;
        long jtTeam = 0L;

        if (ssSign != null && (doctor.equals(ssSign.getDoctor()) ||
                doctor.equals(ssSign.getDoctorHealth()))) {
            ssTeam = ssSign.getAdminTeamId();
        }
        if (jtSign != null && (doctor.equals(jtSign.getDoctor()) ||
                doctor.equals(jtSign.getDoctorHealth()))) {
            jtTeam = jtSign.getAdminTeamId();
        }

        if (labels != null && labels.size() > 0) {
            for (SignPatientLabelInfo label : labels) {
                JSONObject json = new JSONObject(label);

                if (label.getLabelType().equals("4") && !label.getLabel().equals("1") && !label.getLabel().equals("2")) {
                    SignPatientLabel lb = labelService.getLabelByCodeAndType(label.getLabel(), "4");

                    // 有指定团队时不在团队内的过滤
                    if (teamCode > 0 &&lb!=null&& teamCode != lb.getTeamCode()) {
                        continue;
                    }

                    if (teamCode < 1) {
                        // 是否为签约团队标签
                        boolean teamLabelFlag = false;

                        if (ssTeam > 0 &&lb!=null&& ssTeam == (lb.getTeamCode()==null?0:lb.getTeamCode())) {
                            teamLabelFlag = true;
                        }
                        if (jtTeam > 0 &&lb!=null&& jtTeam == (lb.getTeamCode()==null?0:lb.getTeamCode())) {
                            teamLabelFlag = true;
                        }
                        // 有签约关系时，判断标签是否在签约团队标签，不是签约团队标签不显示；无签约关系时返回全部
                        if ((ssTeam > 0 || jtTeam > 0) && !teamLabelFlag) {
                            continue;
                        }
                    }

                    AdminTeam team = adminTeamService.getTeam(lb.getTeamCode());
                    Doctor doc = doctorDao.findByCode(lb.getCreator());

                    json.put("teamCode", team.getId());
                    json.put("teamName", team.getName());
                    json.put("creator", lb==null?null:lb.getCreator());
                    json.put("creatorName", doc.getName());
                }

                result.put(json);
            }
        }

        return result;
    }

    //    =========================================================================================================================================================

    /**
     * 获取没有健康管理师的患者列表
     *
     * @param teamCode
     * @return
     * @throws Exception
     */
    public List findNoHealthSignFamilyHealth(String filter, Long teamCode, int page, int pagesize) throws Exception {
        List list = new ArrayList();
        String sql = "SELECT  DISTINCT " +
                "  p.photo photo, " +
                "  p.name name, " +
                "  p.code code, " +
                "  p.sex sex," +
                "  p.address address," +
                "  p.idcard idcard " +
                " FROM " +
                " wlyy_sign_family sf " +
                " JOIN wlyy_patient p ON sf.patient = p.CODE " +
                " left JOIN wlyy_sign_patient_label_info sp ON sf.patient = sp.patient AND sp.`status` = 1 " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                " and sf.admin_team_code = ? " +
                " AND ( sf.doctor_health is null or sf.doctor_health ='' ) " +
                "  AND (p.name like ? or p.address like ? or p.idcard like ? ) " +
                " ORDER BY  p.name DESC,p.address DESC, p.idcard DESC " +
                " limit " + (page - 1) * pagesize + "," + pagesize;

        List<Map<String, Object>> datas = jdbcTemplate.queryForList(sql, teamCode, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%");
        if (datas != null && datas.size() > 0) {
            for (Map<String, Object> map : datas) {
                Map ma = new HashMap();
                ma.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard") == null ? "" : map.get("idcard").toString()));
                ma.put("photo", map.get("photo") == null ? "" : map.get("photo").toString());
                ma.put("name", map.get("name") == null ? "" : map.get("name").toString());
                ma.put("code", map.get("code") == null ? "" : map.get("code").toString());
                ma.put("sex", map.get("sex") == null ? "" : map.get("sex").toString());
                ma.put("address", map.get("address") == null ? "" : map.get("address").toString());
                ma.put("idcard", map.get("idcard") == null ? "" : map.get("idcard").toString());
                list.add(ma);
            }
        }
        return list;
    }

    /**
     * 根据姓名，地址，身份证号搜索团队内居民
     *
     * @param doctor
     * @param filter
     * @return
     * @throws Exception
     */
    public JSONArray getPatientByParams(String doctor, String filter,
                                        String labelCode, String labelType, long teamCode,
                                        String exLabelCode,
                                        String exLabelType,
                                        int page, int pagesize) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = (page - 1) * pagesize;
        Object[] args = null;
        String sql = "select " +
                "    DISTINCT t1.* " +
                " FROM " +
                "    (wlyy_sign_family t1,wlyy_patient p)  " +
                (StringUtils.isNotEmpty(labelCode) ?
                        " join " : " left join ") +
                "    wlyy_sign_patient_label_info t2 " +
                " ON t1.patient = t2.patient " +
                (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                " WHERE " +
                " p.code = t1.patient " +
                "   AND (t1.doctor = ? or t1.doctor_health = ?) " +
                "    AND t1.status > 0 " +
                "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                (teamCode > 0 ? (" AND admin_team_code = " + teamCode) : "") +
                "  AND (t1.name like ? or p.address like ? or p.idcard like ? ) " +
                " ORDER BY  p.name DESC,p.address DESC, p.idcard DESC ";
        if (StringUtils.isNotEmpty(labelCode)) {
            args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%"};
        } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
            args = new Object[]{doctor, doctor, labelType, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%"};
        } else {
            args = new Object[]{doctor, doctor, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%"};
        }

        sql += " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());
//                  返回的签约类型
                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                if (StringUtils.isNotEmpty(exLabelCode)) {
                    SignPatientLabelInfo labelInfoEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(p.getCode(), exLabelCode, exLabelType, 1);

                    if (labelInfoEx != null) {
                        continue;
                    }
                } else if (StringUtils.isNotEmpty(exLabelType)) {
                    List<SignPatientLabelInfo> labelExs = labelInfoDao.findByPatientAndLabelTypeAndStatus(p.getCode(), exLabelType, 1);

                    if (labelExs != null && labelExs.size() > 0) {
                        continue;
                    }
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }


                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                // 地址（追加）
                json.put("address", p.getAddress() == null ? "" : p.getAddress());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
//                if("2".equals(String.valueOf(sign.get("type"))) && "1".equals(String.valueOf(sign.get("expenses_status")))){
//                    json.put("qyrq", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD) : "");
//                }
                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }
        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }
//    =========================================================================================================================================================

    /**
     * 根据患者姓名或标签名称查询
     *
     * @param doctor
     * @param filter
     * @return
     * @throws Exception
     */
    public JSONArray searchPatientByNameOrLabel(String doctor, String filter,
                                                String labelCode, String labelType, long teamCode,
                                                String exLabelCode,
                                                String exLabelType,
                                                int page, int pagesize) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = page * pagesize;
        Object[] args = null;
        String sql = "";
        //String reg = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
//        String reg = "^(\\d+)([0-9]|X|x)$";
//        匹配数字字符串
        String reg = "[0-9]{1,}";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);

        if (matcher.find()) {
//            sql = " select DISTINCT t.* " +
//                    " from" +
//                    "     wlyy_sign_family t join wlyy_patient p " +
//                    "     on t.patient = p.code " +
//                    (StringUtils.isNotEmpty(labelCode) ? (" join wlyy_sign_patient_label_info l " +
//                            " on t.patient = l.patient ") : "") +
//                    " where " +
//                    "    (t.doctor = ? or t.doctor_health = ?) " +
//                    (teamCode > 0 ? ("    and t.admin_team_code = " + teamCode) : "") +
//                    (StringUtils.isNotEmpty(labelCode) ? " and l.label = ? and l.label_type = ? " : "") +
//                    "     and p.idcard like ? ";
//            if (StringUtils.isNotEmpty(labelCode)) {
//                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%"};
//            } else {
//                args = new Object[]{doctor, doctor, "%" + filter + "%"};
//            }
            sql = "select " +
                    "    DISTINCT t1.* " +
                    " FROM " +
                    "    wlyy_sign_family t1 " +
                    (StringUtils.isNotEmpty(labelCode) ?
                            " join " : " left join ") +
                    "    wlyy_sign_patient_label_info t2 " +
                    " ON t1.patient = t2.patient " +
                    (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                    " WHERE " +
                    "    (t1.doctor = ? or t1.doctor_health = ?) " +
                    "    AND t1.status > 0 " +
                    "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                    (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                    (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                    (teamCode > 0 ? (" AND admin_team_code = " + teamCode) : "") +
                    "  AND (t1.idcard like ?) ";
            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%"};
            } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
                args = new Object[]{doctor, doctor, labelType, "%" + filter + "%"};
            } else {
                args = new Object[]{doctor, doctor, "%" + filter + "%"};
            }
        } else {
            sql = "select " +
                    "    DISTINCT t1.* " +
                    " FROM " +
                    "    wlyy_sign_family t1 " +
                    (StringUtils.isNotEmpty(labelCode) ?
                            " join " : " left join ") +
                    "    wlyy_sign_patient_label_info t2 " +
                    " ON t1.patient = t2.patient " +
                    (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                    " WHERE " +
                    "    (t1.doctor = ? or t1.doctor_health = ?) " +
                    "    AND t1.status > 0 " +
                    "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                    (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                    (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                    (teamCode > 0 ? (" AND admin_team_code = " + teamCode) : "") +
                    "  AND (t1.name like ? or t2.label_name like ?) ";

            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%", "%" + filter + "%"};
            } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
                args = new Object[]{doctor, doctor, labelType, "%" + filter + "%", "%" + filter + "%"};
            } else {
                args = new Object[]{doctor, doctor, "%" + filter + "%", "%" + filter + "%"};
            }
        }

        sql += " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                if (StringUtils.isNotEmpty(exLabelCode)) {
                    SignPatientLabelInfo labelInfoEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(p.getCode(), exLabelCode, exLabelType, 1);

                    if (labelInfoEx != null) {
                        continue;
                    }
                } else if (StringUtils.isNotEmpty(exLabelType)) {
                    List<SignPatientLabelInfo> labelExs = labelInfoDao.findByPatientAndLabelTypeAndStatus(p.getCode(), exLabelType, 1);

                    if (labelExs != null && labelExs.size() > 0) {
                        continue;
                    }
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }


                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
//                if("2".equals(String.valueOf(sign.get("type"))) && "1".equals(String.valueOf(sign.get("expenses_status")))){
//                    json.put("qyrq", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD) : "");
//                }
                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }


    /**
     * 根据患者姓名或标签名称查询
     *
     * @param doctor
     * @param filter
     * @return
     * @throws Exception
     */
    public JSONArray searchPatientByNameOrLabelOverdue(String doctor, String filter,
                                                String labelCode, String labelType, long teamCode,
                                                String exLabelCode,
                                                String exLabelType,
                                                int page, int pagesize) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }

        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = page * pagesize;
        Object[] args = null;
        String sql = "";
        //String reg = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
//        String reg = "^(\\d+)([0-9]|X|x)$";
//        匹配数字字符串
        String reg = "[0-9]{1,}";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);

        if (matcher.find()) {
//            sql = " select DISTINCT t.* " +
//                    " from" +
//                    "     wlyy_sign_family t join wlyy_patient p " +
//                    "     on t.patient = p.code " +
//                    (StringUtils.isNotEmpty(labelCode) ? (" join wlyy_sign_patient_label_info l " +
//                            " on t.patient = l.patient ") : "") +
//                    " where " +
//                    "    (t.doctor = ? or t.doctor_health = ?) " +
//                    (teamCode > 0 ? ("    and t.admin_team_code = " + teamCode) : "") +
//                    (StringUtils.isNotEmpty(labelCode) ? " and l.label = ? and l.label_type = ? " : "") +
//                    "     and p.idcard like ? ";
//            if (StringUtils.isNotEmpty(labelCode)) {
//                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%"};
//            } else {
//                args = new Object[]{doctor, doctor, "%" + filter + "%"};
//            }
            sql = "select " +
                    "    DISTINCT t1.* " +
                    " FROM " +
                    "    wlyy_sign_family t1 " +
                    (StringUtils.isNotEmpty(labelCode) ?
                            " join " : " left join ") +
                    "    wlyy_sign_patient_label_info t2 " +
                    " ON t1.patient = t2.patient " +
                    (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                    " WHERE " +
                    "    (t1.doctor = ? or t1.doctor_health = ?) " +
                    "    AND t1.status= -4 " +
                    "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                    (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                    (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                    (teamCode > 0 ? (" AND admin_team_code = " + teamCode) : "") +
                    "  AND (t1.idcard like ?) ";
            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%"};
            } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
                args = new Object[]{doctor, doctor, labelType, "%" + filter + "%"};
            } else {
                args = new Object[]{doctor, doctor, "%" + filter + "%"};
            }
        } else {
            sql = "select " +
                    "    DISTINCT t1.* " +
                    " FROM " +
                    "    wlyy_sign_family t1 " +
                    (StringUtils.isNotEmpty(labelCode) ?
                            " join " : " left join ") +
                    "    wlyy_sign_patient_label_info t2 " +
                    " ON t1.patient = t2.patient " +
                    (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                    " WHERE " +
                    "    (t1.doctor = ? or t1.doctor_health = ?) " +
                    "    AND t1.status =-4 " +
                    "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                    (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                    (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                    (teamCode > 0 ? (" AND admin_team_code = " + teamCode) : "") +
                    "  AND (t1.name like ? or t2.label_name like ?) ";

            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{doctor, doctor, labelCode, labelType, "%" + filter + "%", "%" + filter + "%"};
            } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
                args = new Object[]{doctor, doctor, labelType, "%" + filter + "%", "%" + filter + "%"};
            } else {
                args = new Object[]{doctor, doctor, "%" + filter + "%", "%" + filter + "%"};
            }
        }

        sql += " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                if (StringUtils.isNotEmpty(exLabelCode)) {
                    SignPatientLabelInfo labelInfoEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(p.getCode(), exLabelCode, exLabelType, 1);

                    if (labelInfoEx != null) {
                        continue;
                    }
                } else if (StringUtils.isNotEmpty(exLabelType)) {
                    List<SignPatientLabelInfo> labelExs = labelInfoDao.findByPatientAndLabelTypeAndStatus(p.getCode(), exLabelType, 1);

                    if (labelExs != null && labelExs.size() > 0) {
                        continue;
                    }
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }


                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
//                if("2".equals(String.valueOf(sign.get("type"))) && "1".equals(String.valueOf(sign.get("expenses_status")))){
//                    json.put("qyrq", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD) : "");
//                }
                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }

    /**
     * 查询所有团队下患者
     *
     * @param filter 搜索关键字
     * @param doctor 医生
     * @return
     */
    public JSONArray searchTeamsPatients(String filter, String doctor, long teamCode, int page, int pagesize) throws Exception {
        JSONArray reArray = new JSONArray();
        Map<String, JSONArray> map = new HashMap<>();
        Map<Long, AdminTeam> teamMap = new HashMap<>();
        List<AdminTeam> teams = null;
        int start = page * pagesize;
        int size = pagesize;

        if (teamCode > 0) {
            teams = new ArrayList<>();
            AdminTeam team = adminTeamService.getTeam(teamCode);
            if (team == null) {
                throw new Exception("adminTeam is not exist");
            }
            teams.add(team);
        } else {
            teams = adminTeamService.getDoctorTeams(doctor);
        }

        String reg = "^(\\d+)([0-9]|X|x)$"; //"(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);
        boolean isIdcard = matcher.find();

        String sql = "select distinct t.* from (" +
                " select " +
                "     f.patient " +
                "     ,f.name " +
                "     ,f.openid " +
                "     ,f.admin_team_code " +
                "     ,p.sex " +
                "     ,p.idcard " +
                "     ,p.photo " +
                " from " +
                "     wlyy_sign_family f,wlyy_patient p " +
                " where " +
                "      f.patient = p.code and (f.doctor = ? or f.doctor_health = ?) and f.admin_team_code = ? and f.status > 0 and " +
                (isIdcard ? " p.idcard like ? " : " f.name like ?") +
                ") " +
                (page < 0 ? "" : "limit " + start + "," + size);

        if (teams != null) {
            for (AdminTeam team : teams) {
                teamMap.put(team.getId(), team);
                List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, new Object[]{doctor, doctor, team.getId(),
                        "%" + filter + "%"});

                if (result != null && result.size() > 0) {
                    for (Map<String, Object> p : result) {
                        JSONObject pJson = new JSONObject();

                        pJson.put("code", p.get("patient"));
                        pJson.put("name", p.get("name") != null ? p.get("name") : "");
                        pJson.put("openid", p.get("openid") != null ? p.get("openid") : "");
                        pJson.put("adminTeamCode", p.get("admin_team_code") != null ? p.get("admin_team_code") : "");
                        pJson.put("sex", p.get("sex") != null ? p.get("sex") : "");
                        pJson.put("age", p.get("idcard") != null ? IdCardUtil.getAgeForIdcard(String.valueOf(p.get("idcard"))) : "");
                        pJson.put("photo", p.get("photo") != null ? p.get("photo") : "");

                        List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndStatus(String.valueOf(p.get("patient")), 1);
                        pJson.put("labels", labels == null ? "" : labels);

                        if (map.containsKey(String.valueOf(p.get("admin_team_code")))) {
                            JSONArray array = map.get(String.valueOf(p.get("admin_team_code")));
                            array.put(pJson);
                        } else {
                            JSONArray array = new JSONArray();
                            array.put(pJson);
                            map.put(String.valueOf(p.get("admin_team_code")), array);
                        }
                    }
                }
            }

            if (map != null && map.size() > 0) {
                for (String key : map.keySet()) {
                    AdminTeam team = teamMap.get(Long.valueOf(key));
                    JSONObject tJson = new JSONObject();

                    tJson.put("teamCode", team.getId());
                    tJson.put("teamName", team.getName());
                    tJson.put("patients", map.get(key));

                    reArray.put(tJson);
                }
            }
        }

        return reArray;
    }

    /**
     * 医生端查询
     *
     * @param filter
     * @return
     */
    public JSONObject search(String filter, String doctorCode) {
        Map<String, JSONObject> teams = new HashMap<>();
        Map<String, JSONObject> patients = new HashMap<>();

        String reg = "^(\\d{6})(19|20)(\\d{2})(1[0-2]|0[1-9])(0[1-9]|[1-2][0-9]|3[0-1])(\\d{3})(\\d|X|x)?$";
        Pattern pattern1 = Pattern.compile(reg); //粗略的校验
        Matcher matcher = pattern1.matcher(filter);
        if (matcher.matches()) {
//            身份证校验通过
            String sql = "SELECT" +
                    "   p. CODE," +
                    "   p. NAME," +
                    "   p.idcard," +
                    "   p.sex," +
                    "   f.id," +
                    "   f.type," +
                    "   f.doctor," +
                    "   f.doctor_health," +
                    "   f.admin_team_code," +
                    "   f. STATUS," +
                    "   t.id teamCode," +
                    "   t.name teamName" +
                    "  FROM" +
                    "   wlyy_patient p" +
                    "  LEFT JOIN (" +
                    "   SELECT" +
                    "    id,type,patient,doctor,doctor_health,admin_team_code,status" +
                    "  FROM" +
                    "   wlyy_sign_family" +
                    "  WHERE" +
                    "   STATUS > 0" +
                    "  AND patient IN (" +
                    "  SELECT" +
                    "   CODE" +
                    "  FROM" +
                    "   wlyy_patient" +
                    "  WHERE" +
                    "   idcard = ?" +
                    ")" +
                    ") f ON p. CODE = f.patient" +
                    "  LEFT JOIN wlyy_admin_team t ON t.id = f.admin_team_code" +
                    "  WHERE" +
                    "   p. idcard = ?";
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, filter, filter);
            for (Map<String, Object> p : list) {
                JSONObject pJson = new JSONObject();

                pJson.put("code", p.get("code"));
                pJson.put("name", p.get("name") != null ? p.get("name") : "");
                pJson.put("idcard", p.get("idcard"));
                pJson.put("sex", p.get("sex") != null ? p.get("sex") : "");
                pJson.put("age", p.get("idcard") != null ? IdCardUtil.getAgeForIdcard(String.valueOf(p.get("idcard"))) : "");
                pJson.put("photo", p.get("photo") != null ? p.get("photo") : "");
                pJson.put("id", p.get("id") != null ? p.get("id") : "");
                pJson.put("doctor", p.get("doctor") != null ? p.get("doctor") : "");
                pJson.put("isSign", p.get("status") != null ? (Integer.parseInt(p.get("status").toString()) >= 1 ? "1" : "0") : "0");
                pJson.put("doctorHealth", p.get("doctor_health") != null ? p.get("doctor_health") : "");
                if (p.get("id") != null && (doctorCode.equals(pJson.get("doctor")) || doctorCode.equals(pJson.get("doctorHealth")))) {
                    if (p.get("teamCode") != null && StringUtils.isNotEmpty(p.get("teamCode").toString())) {
                        JSONObject team = teams.get(p.get("teamCode").toString());
                        if (team == null) {
                            team = new JSONObject();
                            team.put("teamCode", p.get("teamCode"));
                            team.put("teamName", p.get("teamName"));
                            JSONArray pArray = new JSONArray();
                            pArray.put(pJson);
                            team.put("patients", pArray);
                            teams.put(p.get("teamCode").toString(), team);
                        } else {
                            JSONArray pArray = team.getJSONArray("patients");
                            pArray.put(pJson);
                        }
                    }
                } else {
                    patients.put(p.get("code").toString(), pJson);
                }
            }
        } else {
            String sql = "SELECT" +
                    "   p. CODE," +
                    "   p. NAME," +
                    "   p.idcard," +
                    "   p.sex," +
                    "   f.id," +
                    "   f.type," +
                    "   f.doctor," +
                    "   f.doctor_health," +
                    "   f.admin_team_code," +
                    "   f. STATUS," +
                    "   t.id teamCode," +
                    "   t.name teamName" +
                    "  FROM" +
                    "   wlyy_patient p" +
                    "  LEFT JOIN (" +
                    "   SELECT" +
                    "    id,patient,type,doctor,doctor_health,admin_team_code,status" +
                    "  FROM" +
                    "   wlyy_sign_family" +
                    "  WHERE" +
                    "   STATUS > 0" +
                    "  AND patient IN (" +
                    "  SELECT" +
                    "   CODE" +
                    "  FROM" +
                    "   wlyy_patient" +
                    "  WHERE" +
                    "   name = ?" +
                    ")" +
                    ") f ON p. CODE = f.patient" +
                    "  LEFT JOIN wlyy_admin_team t ON t.id = f.admin_team_code" +
                    "  WHERE" +
                    "   p. name  = ?";
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, filter, filter);
            for (Map<String, Object> p : list) {
                JSONObject pJson = new JSONObject();

                pJson.put("code", p.get("code"));
                pJson.put("name", p.get("name") != null ? p.get("name") : "");
                pJson.put("idcard", p.get("idcard"));
                pJson.put("sex", p.get("sex") != null ? p.get("sex") : "");
                pJson.put("age", p.get("idcard") != null ? IdCardUtil.getAgeForIdcard(String.valueOf(p.get("idcard"))) : "");
                pJson.put("photo", p.get("photo") != null ? p.get("photo") : "");
                pJson.put("id", p.get("id") != null ? p.get("id") : "");
                pJson.put("doctor", p.get("doctor") != null ? p.get("doctor") : "");
                pJson.put("isSign", p.get("status") != null ? (Integer.parseInt(p.get("status").toString()) >= 1 ? "1" : "0") : "0");
                pJson.put("doctorHealth", p.get("doctor_health") != null ? p.get("doctor_health") : "");
                if (p.get("id") != null && (doctorCode.equals(pJson.get("doctor")) || doctorCode.equals(pJson.get("doctorHealth")))) {
                    if (p.get("teamCode") != null && StringUtils.isNotEmpty(p.get("teamCode").toString())) {
                        JSONObject team = teams.get(p.get("teamCode").toString());
                        if (team == null) {
                            team = new JSONObject();
                            team.put("teamCode", p.get("teamCode"));
                            team.put("teamName", p.get("teamName"));
                            JSONArray pArray = new JSONArray();
                            pArray.put(pJson);
                            team.put("patients", pArray);
                            teams.put(p.get("teamCode").toString(), team);
                        } else {
                            JSONArray pArray = team.getJSONArray("patients");
                            pArray.put(pJson);
                        }
                    }
                } else {
                    patients.put(p.get("code").toString(), pJson);
                }
            }

        }

        JSONObject result = new JSONObject();
        result.put("teams", teams.values());
        result.put("patients", patients.values());

        return result;
    }

    /**
     * 添加居民到某个标签
     *
     * @param patient   患者
     * @param labelCode 标签code
     * @param labelType 标签类型
     * @return
     */
    public int addPatientLabel(String patient, String labelCode, String labelType) {
        Patient p = patientDao.findByCode(patient);

        if (p == null) {
            return -1;
        }

        SignPatientLabelInfo labelInfo = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, labelCode, labelType, 1);

        if (labelInfo != null) {
            return -2;
        }

        SignPatientLabel label = labelService.getLabelByCodeAndType(labelCode, labelType);

        if (label == null) {
            return -3;
        }

        labelInfo = new SignPatientLabelInfo();

        labelInfo.setPatient(patient);
        labelInfo.setPname(p.getName());
        labelInfo.setLabel(labelCode);
        labelInfo.setLabelType(labelType);
        labelInfo.setLabelName(label.getLabelName());
        labelInfo.setStatus(1);
        labelInfo.setCzrq(new Date());

        labelInfoDao.save(labelInfo);

        return 1;
    }

    /**
     * 添加多个患者到一个标签
     *
     * @param patients
     * @param labelCode
     * @param labelType
     * @return
     */
    public int addPatientsLabel(String patients, String labelCode, String labelType) {
        if (StringUtils.isNotEmpty(patients)) {
            String[] patientArr = patients.split(",");

            for (String p : patientArr) {
                int result = addPatientLabel(p, labelCode, labelType);

                if (result != 1) {
                    return result;
                }
            }
        }

        return 1;
    }

    /**
     * 删除居民的某个标签
     *
     * @param patient   患者
     * @param labelCode 标签code
     * @param labelType 标签类型
     * @return
     */
    public int deletePatientLabel(String patient, String labelCode, String labelType) {
        SignPatientLabelInfo labelInfo = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(patient, labelCode, labelType, 1);

        if (labelInfo == null) {
            return -1;
        }

        labelInfo.setStatus(0);

        labelInfoDao.save(labelInfo);

        return 1;
    }

    /**
     * 删除一个标签下的多个患者
     *
     * @param patients
     * @param labelCode
     * @param labelType
     * @return
     */
    public int deltePatientsLabel(String patients, String labelCode, String labelType) {
        if (StringUtils.isNotEmpty(patients)) {
            String[] patientArr = patients.split(",");

            for (String p : patientArr) {
                int result = deletePatientLabel(p, labelCode, labelType);

                if (result != 1) {
                    return result;
                }
            }
        }

        return 1;
    }


    /**
     * 新增标签并添加患者
     *
     * @param labelName
     * @param creator
     * @param teamCode
     * @param patients
     * @return
     */
    public int addLabelAndPatient(String labelName, String creator, Long teamCode, String patients) {

        if (labelService.isLabelNameExist(labelName, teamCode) != null) {
            return -4;
        }

        SignPatientLabel label = labelService.addLabel(labelName, creator, teamCode);

        if (StringUtils.isNotEmpty(patients)) {
            String[] patientArr = patients.split(",");

            for (String p : patientArr) {
                int result = addPatientLabel(p, label.getLabelCode(), "4");

                if (result != 1) {
                    return result;
                }
            }
        }

        return 1;
    }

    /***BEGIN EXIT DOCTOR***/

    /**
     * 根据患者姓名或标签名称查询
     *
     * @param filter
     * @return
     * @throws Exception
     */
    public JSONArray searchPatientByNameOrLabel(String filter,
                                                String labelCode, String labelType, long teamCode,
                                                String exLabelCode,
                                                String exLabelType,
                                                int page, int pagesize) throws Exception {
        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = page * pagesize;
        Object[] args = null;

        //String reg = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        String reg = "^(\\d+)([0-9]|X|x)$";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);
        String sqlTemp = "";

        if (matcher.find()) {
            sqlTemp = " select DISTINCT t.* " +
                    " from" +
                    "     wlyy_sign_family t join wlyy_patient p " +
                    "     on t.patient = p.code " +
                    (StringUtils.isNotEmpty(labelCode) ? (" join wlyy_sign_patient_label_info l " +
                            " on t.patient = l.patient ") : "") +
                    " where " +
                    "     t.admin_team_code = ? " +
                    (StringUtils.isNotEmpty(labelCode) ? " and l.label = ? and l.label_type = ? " : "") +
                    "     and p.idcard like ? ";
            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{teamCode, labelCode, labelType, "%" + filter + "%"};
            } else {
                args = new Object[]{teamCode, "%" + filter + "%"};
            }
        } else {
            sqlTemp = "select " +
                    "    DISTINCT t1.* " +
                    " FROM " +
                    "    wlyy_sign_family t1 " +
                    (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ?
                            " join " : " left join ") +
                    "    wlyy_sign_patient_label_info t2 " +
                    " ON t1.patient = t2.patient " +
                    (teamCode > 0 ? " join (select * from wlyy_sign_patient_label where label_type != '4' or team_code = " + teamCode + " or (label_type = '4' and (label_code in (1,2)))) lb on t2.label = lb.label_code and t2.label_type = lb.label_type " : "") +
                    " WHERE " +
                    "    t1.status > 0 " +
                    "    AND (" + (StringUtils.isNotEmpty(labelCode) || StringUtils.isNotEmpty(labelType) ? "" : " t2.patient is null OR ") + " t2.status = 1) " +
                    (StringUtils.isNotEmpty(labelCode) ? " AND t2.label = ? " : "") +
                    (StringUtils.isNotEmpty(labelType) ? " AND t2.label_type = ? " : "") +
                    " AND admin_team_code = " + teamCode +
                    "  AND (t1.name like ? or t2.label_name like ?) ";

            if (StringUtils.isNotEmpty(labelCode)) {
                args = new Object[]{labelCode, labelType, "%" + filter + "%", "%" + filter + "%"};
            } else if (StringUtils.isEmpty(labelCode) && StringUtils.isNotEmpty(labelType)) {
                args = new Object[]{labelType, "%" + filter + "%", "%" + filter + "%"};
            } else {
                args = new Object[]{"%" + filter + "%", "%" + filter + "%"};
            }
        }

        sqlTemp += " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sqlTemp, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                if (StringUtils.isNotEmpty(exLabelCode)) {
                    SignPatientLabelInfo labelInfoEx = labelInfoDao.findByPatientAndLabelAndLabelTypeAndStatus(p.getCode(), exLabelCode, exLabelType, 1);

                    if (labelInfoEx != null) {
                        continue;
                    }
                } else if (StringUtils.isNotEmpty(exLabelType)) {
                    List<SignPatientLabelInfo> labelExs = labelInfoDao.findByPatientAndLabelTypeAndStatus(p.getCode(), exLabelType, 1);

                    if (labelExs != null && labelExs.size() > 0) {
                        continue;
                    }
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }

                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }

    /**
     * 查询所有团队下患者
     *
     * @param filter 搜索关键字
     * @return
     */
    public JSONArray searchTeamsPatientsOverdue(String filter, long teamCode, int page, int pagesize) throws Exception {
        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = page * pagesize;
        //String reg = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        String reg = "^(\\d+)([0-9]|X|x)$";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);
        boolean isIdcard = matcher.find();
        Object[] args = new Object[]{teamCode, "%" + filter + "%"};

        String sqlTemp = "select " +
                "    DISTINCT t1.* " +
                " FROM " +
                "    wlyy_sign_family t1 " +
                (isIdcard ? ",wlyy_patient p " : "") +
                " WHERE " +
                (isIdcard ? " t1.patient = p.code  and " : "") +
                "    t1.status =-4 " +
                " AND t1.admin_team_code = ? " +
                "  AND" +
                (isIdcard ? " p.idcard like ? " : " t1.name like ? ");

        String sql = sqlTemp + " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }

                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }

    /**
     * 查询所有团队下患者
     *
     * @param filter 搜索关键字
     * @return
     */
    public JSONArray searchTeamsPatients(String filter, long teamCode, int page, int pagesize) throws Exception {
        Map<String, JSONObject> result = new HashMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        page = page * pagesize;
        //String reg = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        String reg = "^(\\d+)([0-9]|X|x)$";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(filter);
        boolean isIdcard = matcher.find();
        Object[] args = new Object[]{teamCode, "%" + filter + "%"};

        String sqlTemp = "select " +
                "    DISTINCT t1.* " +
                " FROM " +
                "    wlyy_sign_family t1 " +
                (isIdcard ? ",wlyy_patient p " : "") +
                " WHERE " +
                (isIdcard ? " t1.patient = p.code  and " : "") +
                "    t1.status > 0 " +
                " AND t1.admin_team_code = ? " +
                "  AND" +
                (isIdcard ? " p.idcard like ? " : " t1.name like ? ");

        String sql = sqlTemp + " limit " + page + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                List<SignPatientLabelInfo> labels = null;
                if (teamCode > 0) {
                    labels = labelInfoDao.findByPatientAndStatusByTeam(sign.get("patient").toString(), 1, teamCode);
                } else {
                    labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                }

                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        return result.size() > 0 ? new JSONArray(result.values()) : new JSONArray();
    }


    /**
     * 获取团队下的患者(非当前医生而是整个团队)
     *
     * @param teamCode
     * @param page
     * @param pagesize
     * @return
     * @throws Exception
     */
    public JSONArray getPatientByTeamCodeExitDoctor(long teamCode, String labelCode, String labelType, int page, int pagesize) throws Exception {

        Map<String, JSONObject> result = new TreeMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        int start = page * pagesize;
        String sql = "";
        Object[] args = null;

        if (labelType.equals("5")) {
            Calendar today = Calendar.getInstance();
            Calendar startDate = Calendar.getInstance();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            sql = "select * " +
                    " from " +
                    "     wlyy_sign_family " +
                    " where status > 0 and admin_team_code = ? ";

            if (labelCode.equals("1")) {
                int week = today.get(Calendar.DAY_OF_WEEK) - 2;

                if (week == -1) {
                    week = 6;
                }
                startDate.add(Calendar.DATE, -week);
                sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
            } else if (labelCode.equals("2")) {
                startDate.set(Calendar.DATE, 1);
                sql += " and apply_date between '" + (df.format(startDate.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(today.getTime()) + " 23:59:59'");
            } else if (labelCode.equals("3")) {
                startDate.add(Calendar.DATE, 30);
                sql += " and end between '" + (df.format(today.getTime()) + " 00:00:00")
                        + "' and '" + (df.format(startDate.getTime()) + " 23:59:59'");
            } else {
                throw new Exception("label is not exist");
            }
            sql += " order by openid desc,convert(name using gbk) ";
            args = new Object[]{teamCode};
        }else if("1".equals(labelType)){
            int flag =   labelCode.indexOf("-");
            if(flag!=-1){
                String label[] = labelCode.split("-");
                sql = "SELECT " +
                        "    t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1 " +
                        " WHERE t1.status > 0 " +
                        "    AND t1.admin_team_code = ? AND  t1.special_population = '"+label[1]+"'";
                args = new Object[]{teamCode};
            }else{
                sql = "SELECT " +
                        "    t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1 " +
                        " WHERE t1.status > 0 " +
                        "    AND t1.admin_team_code = ? AND  t1.server_type = '"+labelCode+"'";
                args = new Object[]{teamCode};
            }
        }else {
            if (labelCode.equals("0")) {
                sql = "SELECT " +
                        "    DISTINCT  t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1 " +
                        " left join " +
                        "    (select repl.patient,repl.label,repl.label_type,repl.label_name from wlyy_sign_family repf left join wlyy_sign_patient_label_info repl on repf.patient = repl.patient where repf.admin_team_code = ? and repf.status > 0 and repl.label_type = ? and repl.status = 1) t2 " +
                        " on t1.patient = t2.patient " +
                        " WHERE " +
                        "    t2.patient is null " +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? order by t1.openid desc,convert(t1.name using gbk) ";

                args = new Object[]{teamCode, labelType, teamCode};
            } else {
                sql = "SELECT " +
                        "    DISTINCT t1.* " +
                        " FROM " +
                        "    wlyy_sign_family t1, " +
                        "    wlyy_sign_patient_label_info t2 " +
                        " WHERE " +
                        "    t2.label = ? " +
                        "    AND t2.label_type = ? " +
                        "    AND t2.status = 1 " +
                        "    AND t1.patient = t2.patient " +
                        "    AND t1.status > 0 " +
                        "    AND t1.admin_team_code = ? order by t1.openid desc,convert(t1.name using gbk) ";

                args = new Object[]{labelCode, labelType, teamCode};
            }
        }

        sql = sql + " limit " + start + "," + pagesize;
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());

                    if (!String.valueOf(jsonP.get("signType")).equals(String.valueOf(sign.get("type")))) {
                        jsonP.put("signType", 3);
                    }
                    if (String.valueOf(sign.get("type")).equals("2")) {
                        jsonP.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                        // 缴费情况
                        jsonP.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                        // 缴费时间
                        jsonP.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                        // 缴费类型
                        jsonP.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");
                        if (StringUtils.isEmpty(String.valueOf(jsonP.get("expensesStatus"))) || String.valueOf(jsonP.get("expensesStatus")).equals("0")) {
                            boolean epTime = false;
                            try {
                                epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            if (!epTime) {
                                jsonP.put("expensesRemindStatus", 0);
                            } else {
                                jsonP.put("expensesRemindStatus", 1);
                            }
                        }
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            jsonP.put("wechatFocusRemind", 0);
                        } else {
                            jsonP.put("wechatFocusRemind", 1);
                        }
                    }

                    continue;
                }

                //List<SignPatientLabelInfo> labels = labelInfoDao.findByPatientAndStatus(sign.get("patient").toString(), 1);
                JSONObject json = new JSONObject();

                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }
                // 患者标签
                //json.put("labels", labels == null ? "" : labels);

                result.put(p.getCode(), json);
            }
        }

        if (result.size() > 0) {
            List<JSONObject> list = Lists.newArrayList(result.values());

            Collections.sort(list, new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    String openid1 = o1.has("openid") ? o1.getString("openid") : "";
                    String openid2 = o2.has("openid") ? o2.getString("openid") : "";
                    int re = openid1.compareTo(openid2);
                    if (re > 0) {
                        return -1;
                    } else if (re < 0) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });

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

    /**
     * 获取医生所有团队的所有居民
     *
     * @param doctor
     * @return
     * @throws Exception
     */
    public JSONArray getSignPatientsByDoctorCode(String doctor) throws Exception {

        Map<String, JSONObject> result = new TreeMap<>();
        List<Map<String, Object>> signList = new ArrayList<>();
        Object[] args = null;

        String sql = "SELECT " +
                "   t2.label" +
                "   ,t2.label_type labelType" +
                "   ,t3.id teamCode" +
                "   ,t1.* " +
                " FROM " +
                "   wlyy_sign_family t1, " +
                "   wlyy_sign_patient_label_info t2 ," +
                "   (SELECT t.id FROM wlyy_admin_team_member m, wlyy_admin_team t WHERE m.doctor_code = ? AND t.id = m.team_id AND t.available = true AND m.available = true) t3" +
                " WHERE " +
                "   t2.status = 1 " +
                "   AND t1.patient = t2.patient " +
                "   AND t1.status > 0 " +
                "   AND t1.admin_team_code = t3.id ";

        args = new Object[]{doctor};
        signList = jdbcTemplate.queryForList(sql, args);

        if (signList != null && signList.size() > 0) {
            for (Map<String, Object> sign : signList) {
                Patient p = patientDao.findByCode(sign.get("patient") == null ? "" : sign.get("patient").toString());

                if (p == null) {
                    continue;
                }

                if (result.containsKey(p.getCode())) {
                    JSONObject jsonP = result.get(p.getCode());
                    JSONObject signLabel = new JSONObject();
                    signLabel.put("label", sign.get("label"));
                    signLabel.put("labelType", sign.get("labelType"));
                    signLabel.put("teamCode", sign.get("teamCode"));
                    JSONArray ja = jsonP.getJSONArray("signLabel");
                    ja.put(signLabel);

                    continue;
                }

                JSONObject json = new JSONObject();
                JSONObject signLabel = new JSONObject();
                signLabel.put("label", sign.get("label"));
                signLabel.put("labelType", sign.get("labelType"));
                signLabel.put("teamCode", sign.get("teamCode"));
                JSONArray ja = new JSONArray();
                ja.put(signLabel);
                json.put("signLabel",ja);
                // 设置患者标识
                json.put("code", p.getCode());
                // 设置患者姓名
                json.put("name", p.getName());
                // 设置患者手机号
                json.put("mobile", p.getMobile());
                // 设置患者微信openid
                json.put("openid", StringUtils.isNotEmpty(p.getOpenid()) ? p.getOpenid() : "");
                // 设置患者联系电话
                json.put("phone", p.getPhone());
                // 设置患者紧急联系人
                json.put("emerMobile", sign.get("emer_mobile") == null ? "" : String.valueOf(sign.get("emer_mobile")));
                // 设置患者头像
                json.put("photo", p.getPhoto());
                // 设置患者年龄
                json.put("age", IdCardUtil.getAgeForIdcard(p.getIdcard()));
                // 设置患者性别
                json.put("sex", p.getSex());
                // 设置签约日期
                json.put("qyrq", sign.get("apply_date") != null ? DateUtil.dateToStr((Date) sign.get("apply_date"), DateUtil.YYYY_MM_DD) : "");
                // 开始时间
                json.put("begin", sign.get("begin") != null ? DateUtil.dateToStr((Date) sign.get("begin"), DateUtil.YYYY_MM_DD) : "");
                // 结束时间
                json.put("end", sign.get("end") != null ? DateUtil.dateToStr((Date) sign.get("end"), DateUtil.YYYY_MM_DD) : "");
                // 设置签约类型
                json.put("signType", sign.get("type") == null ? "" : sign.get("type"));
                // 身份证号
                json.put("idcard", p.getIdcard());
                // 社保号
                json.put("ssc", p.getSsc());
                //签约类型
                json.put("type", String.valueOf(sign.get("type")));
                if (String.valueOf(sign.get("type")).equals("2")) {
                    // 缴费情况
                    json.put("expensesStatus", sign.get("expenses_status") != null ? String.valueOf(sign.get("expenses_status")) : "0");
                    // 缴费时间
                    json.put("expensesTime", sign.get("expenses_time") != null ? DateUtil.dateToStr((Date) sign.get("expenses_time"), DateUtil.YYYY_MM_DD_HH_MM) : "");
                    // 缴费类型
                    json.put("expensesType", sign.get("expenses_type") != null ? String.valueOf(sign.get("expenses_type")) : "");

                    if (StringUtils.isEmpty(String.valueOf(json.get("expensesStatus"))) || String.valueOf(json.get("expensesStatus")).equals("0")) {
                        boolean epTime = false;
                        try {
                            epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", p.getCode());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (!epTime) {
                            json.put("expensesRemindStatus", 0);
                        } else {
                            json.put("expensesRemindStatus", 1);
                        }
                    }
                } else {
                    // 缴费情况
                    json.put("expensesStatus", "1");
                }
                boolean epTime = false;
                try {
                    epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", p.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!epTime) {
                    json.put("wechatFocusRemind", 0);
                } else {
                    json.put("wechatFocusRemind", 1);
                }

                result.put(p.getCode(), json);
            }
        }

        if (result.size() > 0) {
            List<JSONObject> list = Lists.newArrayList(result.values());
            return new JSONArray(list);
        } else {
            return new JSONArray();
        }
    }

}
