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

import com.yihu.wlyy.entity.consult.Consult;
import com.yihu.wlyy.entity.consult.ConsultTeam;
import com.yihu.wlyy.entity.doctor.OperatorLog;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.doctor.profile.DoctorService;
import com.yihu.wlyy.entity.doctor.team.admin.AdminTeam;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorPatientGroupInfo;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorTeam;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorTeamMember;
import com.yihu.wlyy.entity.doctor.team.sign.SignPatientLabel;
import com.yihu.wlyy.entity.message.Message;
import com.yihu.wlyy.entity.organization.Hospital;
import com.yihu.wlyy.entity.patient.*;
import com.yihu.wlyy.logs.BusinessLogs;
import com.yihu.wlyy.repository.consult.ConsultDao;
import com.yihu.wlyy.repository.consult.ConsultTeamDao;
import com.yihu.wlyy.repository.dict.SystemDictDao;
import com.yihu.wlyy.repository.doctor.*;
import com.yihu.wlyy.repository.message.MessageDao;
import com.yihu.wlyy.repository.organization.HospitalDao;
import com.yihu.wlyy.repository.patient.*;
import com.yihu.wlyy.repository.statistics.WlyySignFamilyCodeDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.service.app.disease.PatientDiseaseService;
import com.yihu.wlyy.service.app.label.SignPatientLabelInfoService;
import com.yihu.wlyy.service.app.message.MessageService;
import com.yihu.wlyy.service.app.scheduling.DoctorWorkTimeService;
import com.yihu.wlyy.service.app.team.AdminTeamService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.task.SignUploadTask;
import com.yihu.wlyy.util.*;
import com.yihu.wlyy.wechat.util.WeiXinAccessTokenUtils;
import com.yihu.wlyy.wechat.util.WeiXinOpenIdUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import java.util.*;

/**
 * 家庭签约业务处理类
 *
 * @author George
 */
@Component
@Transactional
public class FamilyContractService extends BaseService {

    @Autowired
    private DoctorPatientDao doctorPatientDao;
    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private DoctorServiceDao doctorServiceDao;
    @Autowired
    private HospitalDao hospitalDao;
    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private DoctorTeamDao doctorTeamDao;
    @Autowired
    private DoctorTeamMemberDao doctorTeamDoctor;
    @Autowired
    private DoctorPatientGroupInfoDao doctorPatientGroupInfoDao;
    @Autowired
    private ConsultTeamDao consultTeamDao;
    @Autowired
    private WlyySignFamilyCodeDao wlyySignFamilyCodeDao;
    @Autowired
    private SystemDictDao systemDictDao;
    @Autowired
    private PatientDiseaseService patientDiseaseService;
    @Autowired
    private PatientDiseaseDao patientDiseaseDao;
    @Autowired
    private SocialSecurityInfoDao socialSecurityInfoDao;
    @Autowired
    private SignPatientLabelInfoService labelInfoService;
    @Autowired
    private DoctorAdminTeamDao doctorAdminTeamDao;
    @Autowired
    MessageService messageService;
    @Autowired
    AdminTeamService adminTeamService;
    @Autowired
    SignWebService signWebService;

    @Autowired
    SignPatientLabelDao labelDao;
    @Autowired
    SignPatientLabelLogDao labelLogDao;
    @Autowired
    SignPatientLabelInfoDao labelInfoDao;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    WeiXinAccessTokenUtils accessTokenUtils;
    @Autowired
    private DoctorWorkTimeService doctorWorkTimeService;
    @Autowired
    private OperatorLogDao operatorLogDao;
    @Autowired
    private WeiXinOpenIdUtils weiXinOpenIdUtils;
    @Autowired
    private ConsultDao consultDao;
    @Autowired
    private SignFamilyRenewDao signFamilyRenewDao;

    @Autowired
    private SignFamilyMappingDao signFamilyMappingDao;

    public SignFamily findSignFamilyByCode(String code) {
        return signFamilyDao.findByCodeAndType(code, 2);
    }

    public SignFamily findByPatientByType(String patient, int type) {
        return signFamilyDao.findByPatientAndType(patient, type);
    }

    public SignFamily findByPatient(String patient) {
        return signFamilyDao.findByjiatingPatient(patient);
    }

    public SignFamily findSignByPatient(String patient) {
        return signFamilyDao.findSignByPatient(patient);
    }

    /**
     * 获取患者待签约数据
     *
     * @param patient
     * @return
     */
    public SignFamily findSigningByPatient(String patient) {
        return signFamilyDao.findSigningByPatient(patient);
    }

    /**
     * 获取患者待签约数据
     *
     * @param patient
     * @return
     */
    public SignFamily findSigningRenewByPatient(String patient) {
        return signFamilyDao.findSigningByPatient(patient);
    }
    /**
     * 查询医院列表
     *
     * @param type     医院类型：0全部，1大医院，2社区医院
     * @param province 省代码
     * @param city     城市代码
     * @param key      搜索关键字
     * @param id
     * @param pagesize 分页大小
     * @return
     */
    public Page<Hospital> findHospitals(int type, String province, String city, String town, String key, long id, int pagesize) {
        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.ASC, "id");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize, sort);
        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (type == 1) {
            // 查询大医院
            filters.put("level", new SearchFilter("level", Operator.EQ, 1));
        } else if (type == 2) {
            // 查询社区医院
            filters.put("level", new SearchFilter("level", Operator.EQ, 2));
        }
        if (StringUtils.isNotEmpty(province)) {
            filters.put("province", new SearchFilter("province", Operator.EQ, province));
        }
        if (StringUtils.isNotEmpty(city)) {
            filters.put("city", new SearchFilter("city", Operator.EQ, city));
        }
        if (StringUtils.isNotEmpty(town)) {
            filters.put("town", new SearchFilter("town", Operator.EQ, town));
        }
        if (StringUtils.isNotEmpty(key)) {
            filters.put("name", new SearchFilter("name", Operator.LIKE, key));
        }
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.GT, id));
        }
        // 未作废
        filters.put("del", new SearchFilter("del", Operator.EQ, "1"));
        Specification<Hospital> spec = DynamicSpecifications.bySearchFilter(filters.values(), Hospital.class);
        return hospitalDao.findAll(spec, pageRequest);
    }

    /**
     * 查询医院下的医生
     *
     * @param hospital
     * @param level    医生类型：1专科医生，2全科医生，3健康管理师
     * @return
     */
    public Page<Doctor> findDoctors(String hospital, String city, String town, String name, Integer level, Long id, Integer pagesize) {
        if (pagesize == null || pagesize <= 0) {
            pagesize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.ASC, "id");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize, sort);
        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNoneEmpty(hospital)) {
            filters.put("hospital", new SearchFilter("hospital", Operator.EQ, hospital));
        }
        if (!org.springframework.util.StringUtils.isEmpty(city)) {
            filters.put("city", new SearchFilter("city", Operator.EQ, city));
        }
        if (!org.springframework.util.StringUtils.isEmpty(town)) {
            filters.put("town", new SearchFilter("town", Operator.EQ, town));
        }
        if (!org.springframework.util.StringUtils.isEmpty(name)) {
            filters.put("name", new SearchFilter("name", Operator.LIKE, "%" + name + "%"));
        }
        if (id != null && id > 0) {
            filters.put("id", new SearchFilter("id", Operator.GT, id));
        }
        // 医生类型过滤
        if (level != null && level > 0) {
            filters.put("level", new SearchFilter("level", Operator.EQ, level));
        }
        // 未作废
        filters.put("status", new SearchFilter("status", Operator.EQ, 1));
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);
        return doctorDao.findAll(spec, pageRequest);
    }

    /**
     * 根据医生和患者获取患者的签约状态
     *
     * @param patient
     * @param doctor
     * @return
     */
    public List<SignFamily> getSign(String patient, String doctor) {
        List<SignFamily> sfList = signFamilyDao.findSSandFamilyByDoctorPatient(patient, doctor);
        return sfList;
    }

    /**
     * 查询医生主页信息
     *
     * @param doctor  医生标识
     * @param patient 患者标识
     * @return
     */
    public JSONObject findDoctorMainPage(String patient, String doctor) {
        JSONObject json = new JSONObject();
        // 查询医生基本信息
        Doctor d = doctorDao.findByCode(doctor);
        json.put("doctor", d.getCode());
        json.put("evaluateScore", d.getEvaluateScore());
        json.put("name", d.getName());
        json.put("photo", d.getPhoto());
        json.put("sex", d.getSex());
        json.put("job", d.getJob());
        json.put("jobName", d.getJobName());
        json.put("hospital", d.getHospitalName());
        json.put("dept", d.getDeptName());
        json.put("intro", d.getIntroduce());
        json.put("expertise", d.getExpertise());
        json.put("level", d.getLevel());
        // 查询与当前医生的签约状态
        SignFamily sf = null;
        if (d.getLevel() == 2) {
            sf = signFamilyDao.findByDoctorPatient(doctor, patient);
        } else if (d.getLevel() == 3) {
            sf = signFamilyDao.findByDoctorHealthPatient(doctor, patient);
        }

        if (sf == null) {
            // 没有签约信息
            json.put("sign", -1);
        } else {
            // 有签约信息
            json.put("sign", sf.getStatus());
        }
        //设置查看病人所在分组
        List<DoctorPatientGroupInfo> dctorPatientGroupInfo = doctorPatientGroupInfoDao.findByMorenPatient(patient);
        if (dctorPatientGroupInfo != null && dctorPatientGroupInfo.size() > 0) {
            json.put("group", dctorPatientGroupInfo.get(0).getGroup());
        } else {
            json.put("group", "0");
        }
        // 查询医生服务
        List<DoctorService> list = doctorServiceDao.findByDoctor(doctor);
        JSONArray services = new JSONArray();
        for (DoctorService ds : list) {
            if (ds == null) {
                continue;
            }
            JSONObject service = new JSONObject();
            service.put("logo", ds.getLogo());
            service.put("title", ds.getTitle());
            service.put("content", ds.getContent());
            service.put("url", ds.getUrl());
            services.put(service);
        }
        json.put("services", services);
        return json;
    }

    /**
     * 查询患者与医生的签约信息
     *
     * @param patient
     * @param doctor
     * @return
     */
    public int findSignStatus(String patient, String doctor) {
        // 查询与当前医生的签约状态
        SignFamily sf = signFamilyDao.findByDoctorPatient(doctor, patient);
        if (sf == null) {
            // 没有签约信息
            return -1;
        } else {
            // 有签约信息
            return sf.getStatus();
        }
    }

    /**
     * 校验签约状态
     *
     * @return
     * @throws Exception
     */
    public JSONObject checkSign(Patient patient) throws Exception {
        JSONObject json = new JSONObject();
        // 查询是否已存在家庭签约
        SignFamily sf = signFamilyDao.findByIdcard(patient.getIdcard());
        if (sf != null) {
            // 已签约
            json.put("sign", 1);
        } else {
            // 未签约
            json.put("sign", 0);
        }
        return json;
    }

    /**
     * 校验当前openid是否签约家庭医生
     *
     * @return
     */
    public String checkPatient(String patient) {
        SignFamily sf = signFamilyDao.findByjiatingPatientStatus0(patient);
        if (sf != null) {
            return sf.getDoctor();
        }
        return null;
    }

    /**
     * 查询是否存在签约状态
     *
     * @param idcard
     * @return
     */
    public int hasSingStatus(String idcard) {
        return signFamilyDao.hasSingStatus(idcard);
    }

    /**
     * 发起签约申请
     *
     * @param province     省代码
     * @param provinceName 省名称
     * @param city         城市代码
     * @param cityName     城市名称
     * @param town         区县代码
     * @param townName     区县名称
     * @param address      详细地址
     * @param name         患者姓名
     * @param doctor       医生标识
     * @param openid       微信openid
     * @param patient      患者标识
     * @param idcard       患者身份证号
     * @param ssc          患者社保卡号
     * @param mobile       患者手机号
     * @param emerMobile   患者紧急联系人
     * @return
     */
    public JSONObject sign(String province,
                           String provinceName,
                           String city,
                           String cityName,
                           String town,
                           String townName,
                           String address,
                           String name,
                           String doctor,
                           String openid,
                           String patient,
                           String idcard,
                           String ssc,
                           String mobile,
                           String emerMobile) throws Exception {
        // 查询三师签约
        JSONObject json = new JSONObject();
        SignFamily sc = signFamilyDao.findByIdcard(idcard);
        //判断身份证号是否已经注册
        if (sc != null) {
            json.put("res", "-3");
            return json;
        }
        Doctor d = doctorDao.findByCode(doctor);
        SignFamily sf = new SignFamily();
        sf.setCode(getCode());
        // 设置两网编码
        sf.setLwCode(sc != null ? sc.getCode() : null);
        sf.setCzrq(new Date());
        sf.setPatientApplyDate(new Date());
        sf.setDoctor(doctor);
        //设置全科医生的行政团队
        sf.setAdminTeamId(doctorAdminTeamDao.findIdByLeaderCode(doctor));
        sf.setMobile(mobile);
        sf.setDoctorName(d.getName());
        sf.setEmerMobile(emerMobile);
        sf.setName(name);
        sf.setIdcard(idcard);
        sf.setOpenid(openid);
        sf.setPatient(patient);
        sf.setHospital(d.getHospital());
        sf.setHospitalName(d.getHospitalName());
        sf.setSsc(ssc);
        sf.setStatus(0);//0为初始状态
        sf.setType(2);// 设置为家庭签约
        sf.setSignType("1");//用户申请
        sf.setSignSource("2");//签约来源【1 社区签约 2 移动签约】
        //******************扣费接口**********************/
        sf.setExpensesStatus("0");   //扣费状态 【0未扣费 1已扣费 2已退费】
        // 判断用户表是否存在该身份证号
        Patient p = patientDao.findByIdcard(idcard);
        if (p == null) {
            // 插入患者基本信息
            IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
            p = new Patient();
            p.setCode(getCode());
            p.setName(name);
            p.setProvince(province);
            p.setProvinceName(provinceName);
            p.setCity(city);
            p.setCityName(cityName);
            p.setTown(town);
            p.setTownName(townName);
            p.setAddress(address);
            p.setOpenid(openid);
            p.setIdcard(idcard);
            p.setMobile(mobile);
            p.setSsc(ssc);
            // 从身份证号中提取生日
            p.setBirthday(ie.getBirthday());
            // 从身份证号中提取性别
            p.setSex(ie.getGender());
            p.setCzrq(new Date());
            p.setStatus(1);
            // 保存新的用户信息
            p = patientDao.save(p);
        } else {
            if (StringUtils.isNotEmpty(patient) && !StringUtils.equals(p.getCode(), patient)) {
                // 身份证信息与登录信息不匹配
                json.put("res", -1);
                return json;
            }
            if (StringUtils.isNotEmpty(openid) && !StringUtils.equals(p.getOpenid(), openid)) {
                // 身份证信息与登录信息不匹配
                json.put("res", -1);
                return json;
            }
            if (StringUtils.isNotEmpty(idcard) && !StringUtils.equals(p.getIdcard(), idcard)) {
                // 身份证信息与登录信息不匹配
                json.put("res", -1);
                return json;
            }
        }
        // 更新签约用户信息
        patient = p.getCode();
        sf.setPatient(patient);
        SignFamily temp = signFamilyDao.save(sf);
        if (temp != null) {
            // 添加签约消息
            Message message = new Message();
            message.setCzrq(new Date());
            message.setCreateTime(new Date());
            message.setContent("您有一条新的家庭签约申请！");
            message.setRead(1);//设置未读
            message.setReceiver(doctor);//设置接受医生的code
            message.setSender(patient);//设置发送的用户
            message.setSenderName(p.getName());
            message.setCode(getCode());
            message.setSenderPhoto(p.getPhoto());
            message.setTitle("家庭签约申请");
            message.setType(1);//家庭签约信息
            message.setReadonly(1);//是否只读消息
            message.setSignStatus("1");//新的签约
            message.setSex(p.getSex());
            message.setOver("1");//未处理
            message.setData(temp.getCode());
            messageDao.save(message);
            // 发送消息给医生
            // 发送消息给医生
            JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(doctor);
            if (jsonObject.getString("status").equals("1")) {
                //如果在工作时间内就推送
                PushMsgTask.getInstance().put(doctor, MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.D_SW_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.家庭签约.name(), "您有一条新的家庭签约申请！", patient);
            }
        }
        json.put("id", p.getId());
        json.put("uid", p.getCode());
        json.put("res", 1);
        return json;
    }

    /**
     * 申请签约
     *
     * @param doctor  签约医生
     * @param patient 居民code
     * @return
     */
    public int sign(String doctor, String patient) throws Exception {
        Patient p = patientDao.findByCode(patient);
        if (p == null) {
            return -1;
        }

        SignFamily sc = signFamilyDao.findByIdcard(p.getIdcard());
        //判断身份证号是否已签约
        if (sc != null) {
            return -2;
        }

        Doctor d = doctorDao.findByCode(doctor);

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

        SignFamily sf = new SignFamily();

        sf.setCode(getCode());
        // 设置两网编码
        sf.setLwCode(sc != null ? sc.getCode() : null);
        sf.setCzrq(new Date());
        sf.setPatientApplyDate(new Date());

        if (d.getLevel() == 2) {
            sf.setDoctor(doctor);
            sf.setDoctorName(d.getName());
        } else {
            sf.setDoctorHealth(doctor);
            sf.setDoctorHealthName(d.getName());
        }

        sf.setMobile(p.getMobile());
        sf.setName(p.getName());
        sf.setIdcard(p.getIdcard());
        sf.setOpenid(p.getOpenid());
        sf.setPatient(patient);
        sf.setHospital(d.getHospital());
        sf.setHospitalName(d.getHospitalName());
        sf.setSsc(p.getSsc());
        sf.setStatus(0);//0为初始状态
        sf.setType(2);// 设置为家庭签约
        sf.setSignType("1");//用户申请
        sf.setSignSource("2");//签约来源【1 社区签约 2 移动签约】
        //******************扣费接口**********************/
        sf.setExpensesStatus("0");   //扣费状态 【0未扣费 1已扣费 2已退费】
        sf.setBegin(DateUtil.stringToDate(DateUtil.getSignYear()+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));
        sf.setEnd(DateUtil.stringToDate(DateUtil.getSignYear()+1+"-06-30 23:59:59","yyyy-MM-dd HH:mmm:ss"));

        SignFamily temp = signFamilyDao.save(sf);

        if (temp != null) {
            // 添加签约消息
            Message message = new Message();
            message.setCzrq(new Date());
            message.setCreateTime(new Date());
            message.setContent("您有一条新的家庭签约申请！");
            message.setRead(1);//设置未读
            message.setReceiver(doctor);//设置接受医生的code
            message.setSender(patient);//设置发送的用户
            message.setSenderName(p.getName());
            message.setCode(getCode());
            message.setSenderPhoto(p.getPhoto());
            message.setTitle("家庭签约申请");
            message.setType(1);//家庭签约信息
            message.setReadonly(1);//是否只读消息
            message.setSignStatus("1");//新的签约
            message.setSex(p.getSex());
            message.setOver("1");//未处理
            message.setData(temp.getCode());
            messageDao.save(message);
            // 发送消息给医生
            JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(doctor);
            if (jsonObject.getString("status").equals("1")) {
                //如果在工作时间内就推送
                PushMsgTask.getInstance().put(doctor, MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.D_SW_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.家庭签约.name(), "您有一条新的家庭签约申请！", patient);
            }
        }

        return 1;
    }

    /**
     * 取消签约申请
     *
     * @param patient 患者标识
     * @param doctor  医生标识
     * @return
     */
    public int unsign(String patient, String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            throw new Exception("doctor info can not find");
        }
        //修改签约标识为无效
        SignFamily sf = null;

        if (doc.getLevel() == 2) {
            sf = signFamilyDao.findByDoctorPatient(doctor, patient);
        } else if (doc.getLevel() == 3) {
            sf = signFamilyDao.findByDoctorHealthPatient(doctor, patient);
        }
        if (sf.getStatus() != 0 && sf.getStatus() != 2) {
            return -2;
        }
        if (sf != null) {
            sf.setStatus(-1);
        } else {
            return -2;
        }
        //结束与医生所有消息
        List<Message> messages = messageDao.findByPatient(patient, doctor);
        if(messages!=null&&messages.size()>0){
            for(Message message:messages){
                //修改信息为无效
                if (message != null) {
                    message.setRead(0);
                    message.setOver("0");
                }
            }
        }
        return 200;
    }

    /**
     * 取消续签
     * @param patient
     * @param doctor
     * @return
     * @throws Exception
     */
    public int unsignRenew(String patient, String doctor) throws Exception {

        if(DateUtil.getNowMonth()<7){
            SignFamilyRenew  sf = signFamilyRenewDao.findByDoctorPatient(doctor, patient);
            if (sf!=null&&sf.getStatus() != 0 && sf.getStatus() != 2) {
                return -2;
            }
            sf.setStatus(-1);
        }else{
            SignFamily  sf = signFamilyDao.findByDoctorPatient(doctor, patient);
            if (sf!=null&&sf.getStatus() != 0 && sf.getStatus() != 2) {
                return -2;
            }
            sf.setStatus(-1);
        }

        //结束与医生所有消息
        List<Message> messages = messageDao.findByPatientRenew(patient, doctor);

        if(messages!=null&messages.size()>0){
            for(Message message:messages){
                //修改信息为无效
                if (message != null) {
                    message.setRead(0);
                    message.setOver("0");
                    messageDao.save(message);
                }
            }
        }

        return 200;
    }

    /**
     * 申请解约
     *
     * @param patient 患者标识
     * @param doctor  医生标识
     * @param openid  微信openid
     * @param reason  解约理由
     * @return
     */
    public int surrender(String patient, String patientName, String userPhoto, String doctor, String doctorName, String openid, String reason, int sex) throws Exception {
        // 更新为待解约
        int res = signFamilyDao.surrender(patient, doctor);
        SignFamily signFamily = signFamilyDao.findByjiatingPatient(patient);
        signFamily.setPatientApplyUnsignDate(new Date());
        if (res == 0) {
            return 0;
        }
        // 添加签约消息
        Message message = new Message();
        // 消息时间
        message.setCzrq(new Date());
        message.setCreateTime(new Date());
        // 消息内容
        message.setContent("申请解除与您的签约关系");
        // 未读
        message.setRead(1);
        message.setReceiverName(doctorName);
        // 接收人
        message.setReceiver(doctor);
        message.setCode(getCode());
        // 发送人
        message.setSender(patient);
        message.setSenderName(patientName);
        message.setSenderPhoto(userPhoto);
        // 标题
        message.setTitle("解除家庭签约申请");
        message.setType(1);
        message.setSignStatus("4");
        message.setReadonly(1);
        message.setSex(sex);
        message.setOver("1");
        // 设置解约理由
        message.setReason(reason);
        message.setData(signFamily.getCode());
        messageDao.save(message);
        // 发送消息给医生
        JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(doctor);
        if (jsonObject.getString("status").equals("1")) {
            //如果在工作时间内就推送
            PushMsgTask.getInstance().put(doctor, MessageType.MESSAGE_TYPE_DOCTOR_SIGN_WEB_RELIEVE.D_SW_02.name(), MessageType.MESSAGE_TYPE_DOCTOR_SIGN_WEB_RELIEVE.家庭签约.name(), patientName + " 申请解除与您的家庭签约！", patient);
        }
        return 1;
    }

    /**
     * 查询患者的签约消息
     *
     * @param id
     * @param pagesize
     * @return
     */
    public Page<Message> findMessageByPatient(String patient, long id, int pagesize) {
        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.DESC, "id");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize, sort);
        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        filters.put("receiver", new SearchFilter("receiver", Operator.EQ, patient));
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.LT, id));
        }
        Specification<Message> spec = DynamicSpecifications.bySearchFilter(filters.values(), Message.class);
        return messageDao.findAll(spec, pageRequest);
    }

    /**
     * 查询跟医生相关的家庭签约信息
     *
     * @param type     0全部，1待签约，2已签约，3待解约，4已解约
     * @param id
     * @param pagesize 分页大小
     * @return
     */
    public Page<SignFamily> findSignByDoctor(int type, long id, int pagesize) {
        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.DESC, "id");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize, sort);
        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        // 只查家庭签约（网络签约）
        filters.put("type", new SearchFilter("type", Operator.EQ, 2));
        switch (type) {
            case 1:
                // 待签约
                filters.put("status", new SearchFilter("status", Operator.EQ, 0));
                break;
            case 2:
                // 已签约
                filters.put("status", new SearchFilter("status", Operator.EQ, 1));
                break;
            case 3:
                // 待解约
                filters.put("status", new SearchFilter("status", Operator.EQ, 2));
                break;
            case 4:
                // 已解约
                filters.put("status", new SearchFilter("status", Operator.EQ, -3));
                break;
        }
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.LT, id));
        }
        Specification<SignFamily> spec = DynamicSpecifications.bySearchFilter(filters.values(), SignFamily.class);
        return signFamilyDao.findAll(spec, pageRequest);
    }

    /**
     * 代理签约
     *
     * @param name             患者姓名
     * @param doctor           医生标识
     * @param doctorName       医生姓名
     * @param doctorHealth     健康管理师标识
     * @param doctorHealthName 健康管理师姓名
     * @param hospital         签约医院标识
     * @param hospitalName     签约医院名称
     * @param idcard           患者身份证号
     * @param ssc              患者社保卡号
     * @param mobile           患者手机号
     * @param emerMobile       患者紧急联系人
     * @param expenses
     * @return
     * @throws Exception
     */
    synchronized public SignFamily agent(String access_token, String name,
                                         String doctor, String doctorName,
                                         String doctorHealth, String doctorHealthName,
                                         String hospital, String hospitalName,
                                         String idcard, String ssc,
                                         String mobile,
                                         String emerMobile, String images,
                                         String healthLabel, String customLabel, String disease,
                                         String expenses, String signDoctorCode,
                                         String signDoctorName, String signDoctorLevel, long adminTeamCode,String sevId) throws Exception {
        // 查询是否有家庭签约
        SignFamily sc = signFamilyDao.findByIdcard(idcard);
        if (sc != null) {
            throw new Exception("已签约了家庭医生！");
        }
        //判断是否有三师签约 并且判断全科医生一致
        //屏蔽三师签约判断
//        SignFamily sssignFamily = signFamilyDao.findSSByIdcard(idcard);
//        if (sssignFamily != null && !doctor.equals(sssignFamily.getDoctor())) {
//            throw new Exception("全科医生不一致！");
//        }

//        List<SystemDict> systemDicts = systemDictDao.findByDictName("SIGN_YEAR");
        Calendar cal = Calendar.getInstance();
        int m = cal.get(Calendar.MONTH)+1;
        String signYear = "" ;
        if(m>=4){
            //签约当前年度
            signYear = cal.get(Calendar.YEAR)+"";
        }else{
            //签约过去年度
            signYear = (cal.get(Calendar.YEAR)-1)+"";
        }

        SignFamily sf = new SignFamily();
        sf.setSignYear(DateUtil.getSignYear()+"");//设置签约年度
        sf.setBegin(DateUtil.getNowDateShort());
        sf.setCode(getCode());
        sf.setCzrq(new Date());

        //设置全科医生的行政团队
        sf.setAdminTeamId(adminTeamCode);

        AdminTeam team = doctorAdminTeamDao.findOne(adminTeamCode);
        Doctor docLeader = doctorDao.findByCode(team.getLeaderCode());

        //设置签约医生
        sf.setSignDoctorCode(docLeader.getCode());
        sf.setSignDoctorName(docLeader.getName());
        sf.setSignDoctorLevel(String.valueOf(docLeader.getLevel()));

        sf.setDoctor(doctor);
        sf.setDoctorName(doctorName);
        sf.setDoctorHealth(doctorHealth);
        sf.setDoctorHealthName(doctorHealthName);
        sf.setExpensesType(StringUtils.isEmpty(expenses) ? "01" : expenses);
        //sf.setFamilyCode(createSignCode(doctor, hospital));
        sf.setEmerMobile(emerMobile);
        sf.setEnd(DateUtil.strToDateShort(DateUtil.getNextYear(DateUtil.getNowDateShort(), 1)));
        sf.setName(name);
        sf.setIdcard(idcard);
        sf.setMobile(mobile);
        sf.setHospital(hospital);
        sf.setHospitalName(hospitalName);
        String sscD = "";
        if (StringUtils.isNumeric(ssc.trim())) {
            //如果是纯数字的医保号换成D开头的
            sscD = socialSecurityInfoDao.findBySfzh18Max(idcard).getCardno();
        } else {
            sscD = ssc;
        }
        sf.setSsc(sscD);
        sf.setStatus(1);// 代理签约，直接生效
        sf.setImages(images);
        sf.setApplyDate(new Date());
        sf.setType(2);// 设置为家庭签约
        sf.setSignType("2");//手工带签
        sf.setAgentDoctorCode(signDoctorCode);
        sf.setAgentDoctorLevel(signDoctorLevel);
        sf.setAgentDoctorName(signDoctorName);
        sf.setSignSource("2");//签约来源【1 社区签约 2 移动签约】
        //******************扣费接口**********************/
        sf.setExpensesStatus("0");   //扣费状态 【0未扣费 1已扣费 2已退费】
        //设置1.3.3.2服务信息
        if(StringUtils.isNotBlank(sevId)){
            signWebService.setSevId(sf,sevId);
        }
        // 查询该患者是否已注册
        Patient patient = patientDao.findByIdcard(idcard);
        if (patient == null) {
            // 插入患者基本信息
            IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
            patient = new Patient();
            patient.setCode(getCode());
            patient.setName(name);
            patient.setIdcard(idcard);
            patient.setSsc(sscD);
            patient.setMobile(mobile);
            patient.setBirthday(ie.getBirthday());
            patient.setSex(ie.getGender());
            String password = idcard.substring(idcard.length() - 6);
            String salt = UUID.randomUUID().toString().replace("-", "");
            patient.setSalt(salt);
            patient.setPassword(MD5.GetMD5Code(password + salt));
            patient.setStatus(1);
            patient.setDisease(0);
        }

        // 保存用户信息
        patientDao.save(patient);

        Calendar now = Calendar.getInstance();
        int month = now.get(Calendar.MONTH) + 1;
        Calendar begin = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        // 起始时间
//        begin.set(Calendar.HOUR, 0);
//        begin.set(Calendar.MINUTE, 0);
//        end.set(Calendar.SECOND, 0);
//        begin.set(Calendar.MILLISECOND, 0);
//
//        // 结束时间
//        end.set(Calendar.HOUR, 0);
//        end.set(Calendar.MINUTE, 0);
//        end.set(Calendar.SECOND, 0);
//        end.set(Calendar.MILLISECOND, 0);
//        end.set(Calendar.MONTH, 5);
//        end.set(Calendar.DATE, 30);
//
//        if (month < 2 || month > 5) {
//            if (month > 5) {
//                end.add(Calendar.YEAR, 1);
//            }
//        } else {
//            begin.set(Calendar.MONTH, 6);
//            begin.set(Calendar.DATE, 1);
//            end.add(Calendar.YEAR, 1);
//        }

        // 更新签约日期
        sf.setBegin(DateUtil.stringToDate(DateUtil.getSignYear()+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));
        sf.setEnd(DateUtil.stringToDate(DateUtil.getSignYear()+1+"-06-30 23:59:59","yyyy-MM-dd HH:mmm:ss"));

        sf.setOpenid(patient.getOpenid());
        sf.setPatient(patient.getCode());
        // 改为签约生效
        sf.setStatus(1);
        //建立团队
        DoctorTeam doctorTeam = new DoctorTeam();
        String doctorTeamCode = getCode();
        doctorTeam.setCode(doctorTeamCode);
        doctorTeam.setCzrq(new Date());
        doctorTeam.setName("团队名称:" + name);
        doctorTeam.setSignType("2");//家庭签约
        doctorTeam.setDel("1");
        doctorTeamDao.save(doctorTeam);
        sf.setTeamCode(doctorTeamCode);
        signFamilyDao.save(sf);
        //添加团队成员
        //添加健康管理师
        DoctorTeamMember wlyyDoctorTeamDoctor = new DoctorTeamMember();
        wlyyDoctorTeamDoctor.setTeam(doctorTeamCode);
        wlyyDoctorTeamDoctor.setMemberCode(doctorHealth);
        wlyyDoctorTeamDoctor.setName(doctorHealthName);
        wlyyDoctorTeamDoctor.setDel("1");
        wlyyDoctorTeamDoctor.setType(3);
        wlyyDoctorTeamDoctor.setSignType("2");//家庭签约
        wlyyDoctorTeamDoctor.setCode(getCode());
        wlyyDoctorTeamDoctor.setCzrq(new Date());
        doctorTeamDoctor.save(wlyyDoctorTeamDoctor);
        //添加全科医生
        wlyyDoctorTeamDoctor = new DoctorTeamMember();
        wlyyDoctorTeamDoctor.setTeam(doctorTeamCode);
        wlyyDoctorTeamDoctor.setMemberCode(doctor);
        wlyyDoctorTeamDoctor.setName(doctorName);
        wlyyDoctorTeamDoctor.setDel("1");
        wlyyDoctorTeamDoctor.setType(2);
        wlyyDoctorTeamDoctor.setSignType("2");//家庭签约
        wlyyDoctorTeamDoctor.setCode(getCode());
        wlyyDoctorTeamDoctor.setCzrq(new Date());
        doctorTeamDoctor.save(wlyyDoctorTeamDoctor);

        //添加患者和团队的关系
        DoctorTeamMember wlyyDoctorTeamPatient = new DoctorTeamMember();
        wlyyDoctorTeamPatient.setTeam(doctorTeamCode);
        wlyyDoctorTeamPatient.setMemberCode(patient.getCode());
        wlyyDoctorTeamPatient.setName(patient.getName());
        wlyyDoctorTeamPatient.setDel("1");
        wlyyDoctorTeamPatient.setSignType("2");//家庭签约
        wlyyDoctorTeamPatient.setType(5);
        wlyyDoctorTeamPatient.setCode(getCode());
        wlyyDoctorTeamPatient.setCzrq(new Date());
        doctorTeamDoctor.save(wlyyDoctorTeamPatient);

        // 患者标签设置
        if (!(labelInfoService.setPatientLabels(patient.getCode(), patient.getIdcard(),
                patient.getName(), healthLabel, disease, customLabel, sf.getDoctor(), signDoctorCode) == 1)) {
            throw new Exception("patient sign label settting error:" + patient.getIdcard());
        }

        SignFamily temp = signFamilyDao.save(sf);

        //设置基卫标识1.3.3.2版本更新
        setSignFamilyMapping(temp.getCode(),temp.getIdcard(),temp.getSignYear());

        if (temp != null && patient != null) {
            Doctor doc = doctorDao.findByCode(sf.getDoctor());
            Hospital hos = hospitalDao.findByCode(doc.getHospital());

            String content = sf.getName() + "，您好！祝贺您，成功签约" + sf.getDoctorName() + "医生团队，您已可以享受家庭医生所带来的无微不至的健康保健服务。" +
                    "为了给您提供更好的服务，请尽快到" + (hos != null ? hos.getName() : "") + "社区（地址：" +
                    (hos != null ? hos.getAddress() : "") + "）缴费。";
            JSONObject json = new JSONObject();
            json.put("first", "签约成功通知");
            json.put("toUser", sf.getPatient());
            json.put("represented",sf.getPatient());//被代理人
            json.put("doctor", sf.getDoctor());
            json.put("doctorName", sf.getDoctorName());
            json.put("date", DateUtil.dateToStrShort(sf.getBegin()));
            json.put("content", content);
            json.put("remark", ""); //您好，您成功签约家庭医生
            if (StringUtils.isNotBlank(sf.getOpenid())) {
                // 添加到发送队列
                PushMsgTask.getInstance().putWxMsg(access_token, 1, sf.getOpenid(), sf.getName(), json);
            } else {
                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(patient.getCode());
                if (j != null) {
                    Patient member = (Patient) j.get("member");
                    if (StringUtils.isNotBlank(member.getOpenid())) {
                        //String first = (String) json.get("first");
                        json.remove("first");
                        json.put("first", weiXinOpenIdUtils.getTitleMes(patient, j.getInt("relation"), sf.getName()));
                        PushMsgTask.getInstance().putWxMsg(access_token, 1, member.getOpenid(), sf.getName(), json);
                    }
                }
            }
            new Thread(new SignUploadTask(sf.getCode())).start();
            JSONObject participants = new JSONObject();
            participants.put(sf.getPatient(), 0);
            if (StringUtils.equals(sf.getDoctor(), sf.getDoctorHealth())) {//全科和建管同一个人
                participants.put(sf.getDoctor(), 0);
            } else {//全科和建管不同一个人
                participants.put(sf.getDoctorHealth(), 0);
                participants.put(sf.getDoctor(), 1);
            }
            //创建医生会话讨论组
            JSONObject sessionObj = ImUtill.createSession(participants, ImUtill.SESSION_TYPE_MUC, patient.getName(), patient.getCode() + "_" + sf.getTeamCode() + "_" + 2);
            if (sessionObj.getInt("status") == -1) {
                throw new RuntimeException(sessionObj.getString("message"));
            }
            ImUtill.updateSessionStatus(patient.getCode() + "_" + sf.getTeamCode() + "_" + 2, ImUtill.SESSION_STATUS_END);

            ImUtill.sendImMsg(doc.getCode(), doc.getName(), patient.getCode() + "_" + sf.getTeamCode() + "_" + 2, "0", "家庭医生代理签约成功！", "1");
        }
        BusinessLogs.info(BusinessLogs.BusinessType.sign, signDoctorCode, sf.getPatient(), new JSONObject(sf));
        return temp;
    }

    /**
     * 处理签约申请
     *
     * @param healthDoctor     健康管理师标识
     * @param healthDoctorName 健康管理师姓名
     * @param msgid            消息id
     * @param patientCard      患者身份证
     * @param type             处理类型：1同意，2拒绝
     * @return
     */

    public JSONObject handleSign(String signType,
                                 String access_token,
                                 String doctor,
                                 String doctorName,
                                 String healthDoctor,
                                 String healthDoctorName,
                                 long msgid,
                                 String patientCard, int type,
                                 String healthLabel, String customLabel, String disease,
                                 String expenses, long adminTeamCode,
                                 String sevId) throws Exception {
        JSONObject result = new JSONObject();
        String caller = "";
        if (type != 1 && type != 2) {
            result.put("status", -1);
            return result;
        }

        // 查询患者信息
        Patient p = patientDao.findByIdcard(patientCard);

        // 更新消息状态为已处理
        if (msgid > 0) {
            Message message = messageDao.findOne(msgid);
            message.setRead(0);//设置已读
            message.setOver("0");//设置消息操作结束
            message.setCzrq(new Date());
        }
        // 判断患者有没有家庭签约
        SignFamily sf = signFamilyDao.findByPatientStatus(patientCard, 0);
        if (sf == null) {
            result.put("status", 0);
            return result;
        }
        String doctorTeamCode = null;//服务团队的CODE;
        //医生同意逻辑
        if (type == 1) {

            //2017-5-27 屏蔽三师签约判断
            //判断是否有三师签约 并且判断全科医生一致
//            SignFamily sssignFamily = signFamilyDao.findSSByIdcard(p.getIdcard());
//
//            if (sssignFamily != null) {
//                if (StringUtils.isNotEmpty(doctor)) {
//                    if (!doctor.equals(sssignFamily.getDoctor())) {
//                        result.put("status", -2);
//                        result.put("msg", "居民已签约三师，故全科医生只可为" + sssignFamily.getDoctorName() + "医生，请重新选择全科医生");
//                        return result;
//                    }
//                    List<AdminTeam> teams = adminTeamService.findDoctorsTeams(sf.getDoctorHealth(), sssignFamily.getDoctor());
//
//                    if (teams == null || teams.size() < 1) {
//                        result.put("status", -4);
//                        result.put("msg", "居民已签约三师，三师签约的全科医生" + sssignFamily.getDoctorName() + "与该签约申请的健管师" + sf.getDoctorHealthName() + "不在同一个团队，该签约申请已失效");
//                        messageService.readHealth(msgid);
//                        updateSignStatus(p.getIdcard());
//                        return result;
//                    }
//                }
//                if (StringUtils.isNotEmpty(healthDoctor) && !sf.getDoctor().equals(sssignFamily.getDoctor())) {
//                    result.put("status", -3);
//                    result.put("msg", "对不起，居民已签约三师，故只可与" + sssignFamily.getDoctorName() + "医生签约，该签约申请已失效");
//                    messageService.readHealth(msgid);
//                    updateSignStatus(p.getIdcard());
//                    return result;
//                }
//            }

            //List<SystemDict> systemDicts = systemDictDao.findByDictName("SIGN_YEAR");
            Calendar cal = Calendar.getInstance();
            int m = cal.get(Calendar.MONTH)+1;
            String year = "" ;
            if(m>=4){
                //签约当前年度
                year = cal.get(Calendar.YEAR)+"";
            }else{
                //签约过去年度
                year = (cal.get(Calendar.YEAR)-1)+"";
            }

            Calendar now = Calendar.getInstance();
            int month = now.get(Calendar.MONTH) + 1;
            Calendar begin = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            // 起始时间
            begin.set(Calendar.HOUR, 0);
            begin.set(Calendar.MINUTE, 0);
            begin.set(Calendar.SECOND, 0);
            begin.set(Calendar.MILLISECOND, 0);

            // 结束时间
            end.set(Calendar.HOUR, 0);
            end.set(Calendar.MINUTE, 0);
            end.set(Calendar.SECOND, 0);
            end.set(Calendar.MILLISECOND, 0);
            end.set(Calendar.MONTH, 7);
            end.set(Calendar.DATE, 1);

            if (month < 2 || month > 5) {
                if (month > 5) {
                    end.add(Calendar.YEAR, 1);
                }
            } else {
                begin.set(Calendar.MONTH, 6);
                begin.set(Calendar.DATE, 1);
                end.add(Calendar.YEAR, 1);
            }

            // 更新签约日期
            sf.setBegin(DateUtil.stringToDate(DateUtil.getSignYear()+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));
            sf.setEnd(DateUtil.stringToDate(DateUtil.getSignYear()+1+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));


            // 改为签约生效
            sf.setStatus(1);
            sf.setSignType("1");//患者发起签约
            sf.setExpensesType(StringUtils.isEmpty(expenses) ? "01" : expenses);//收费类别
            sf.setAdminTeamId(adminTeamCode);
            //设置服务类型1.3.3.2版本更新
            if(StringUtils.isNotBlank(sevId)){
                signWebService.setSevId(sf,sevId);
            }
            if (StringUtils.isNotEmpty(doctor)) {
                //设置全科医生
                sf.setDoctor(doctor);
                sf.setDoctorName(doctorName);
                caller = sf.getDoctorHealth();
            } else {
                // 更新健康管理师
                sf.setDoctorHealth(healthDoctor);
                sf.setDoctorHealthName(healthDoctorName);
                caller = sf.getDoctor();
            }

            AdminTeam team = doctorAdminTeamDao.findOne(adminTeamCode);
            Doctor docLeader = doctorDao.findByCode(team.getLeaderCode());

            //设置签约医生
            sf.setSignDoctorCode(docLeader.getCode());
            sf.setSignDoctorName(docLeader.getName());
            sf.setSignDoctorLevel(String.valueOf(docLeader.getLevel()));

            sf.setCzrq(new Date());
            sf.setSignYear(DateUtil.getSignYear()+"");//设置签约年度
            sf.setApplyDate(new Date());
            Doctor doc = doctorDao.findByCode(sf.getDoctor());
            //sf.setFamilyCode(createSignCode(sf.getDoctor(), doc.getHospital()));
            //建立团队
            DoctorTeam doctorTeam = new DoctorTeam();
            doctorTeamCode = getCode();
            doctorTeam.setName("签约团队患者:" + p.getName());
            doctorTeam.setCode(doctorTeamCode);
            doctorTeam.setCzrq(new Date());
            doctorTeam.setSignType("2");
            doctorTeam.setDel("1");
            doctorTeamDao.save(doctorTeam);
            sf.setTeamCode(doctorTeamCode);
            //添加团队成员
            //添加健康管理师
            DoctorTeamMember wlyyDoctorTeamDoctor = new DoctorTeamMember();
            wlyyDoctorTeamDoctor.setTeam(doctorTeamCode);
            wlyyDoctorTeamDoctor.setMemberCode(sf.getDoctorHealth());
            wlyyDoctorTeamDoctor.setName(sf.getDoctorHealthName());
            wlyyDoctorTeamDoctor.setDel("1");

            wlyyDoctorTeamDoctor.setSignType("2");
            wlyyDoctorTeamDoctor.setType(3);
            wlyyDoctorTeamDoctor.setCode(getCode());
            wlyyDoctorTeamDoctor.setCzrq(new Date());
            doctorTeamDoctor.save(wlyyDoctorTeamDoctor);
            //添加全科医生
            wlyyDoctorTeamDoctor = new DoctorTeamMember();
            wlyyDoctorTeamDoctor.setTeam(doctorTeamCode);
            wlyyDoctorTeamDoctor.setMemberCode(sf.getDoctor());
            wlyyDoctorTeamDoctor.setSignType("2");//家庭签约
            wlyyDoctorTeamDoctor.setName(sf.getDoctorName());
            wlyyDoctorTeamDoctor.setDel("1");
            wlyyDoctorTeamDoctor.setType(2);
            wlyyDoctorTeamDoctor.setCode(getCode());
            wlyyDoctorTeamDoctor.setCzrq(new Date());
            doctorTeamDoctor.save(wlyyDoctorTeamDoctor);
            //添加患者和团队的关系
            DoctorTeamMember wlyyDoctorTeamPatient = new DoctorTeamMember();
            wlyyDoctorTeamPatient.setTeam(doctorTeamCode);
            wlyyDoctorTeamPatient.setMemberCode(sf.getPatient());
            wlyyDoctorTeamPatient.setName(p.getName());
            wlyyDoctorTeamPatient.setDel("1");
            wlyyDoctorTeamPatient.setSignType("2");//家庭签约
            wlyyDoctorTeamPatient.setType(5);//患者
            wlyyDoctorTeamPatient.setCode(getCode());
            wlyyDoctorTeamPatient.setCzrq(new Date());
            doctorTeamDoctor.save(wlyyDoctorTeamPatient);

            //设置基卫标识1.3.3.2版本更新
            setSignFamilyMapping(sf.getCode(),sf.getIdcard(),sf.getSignYear());

        } else {
            // 医生拒绝
            sf.setStatus(-2);
            sf.setCzrq(new Date());
            // 拒绝签约
            JSONObject json = new JSONObject();
            json.put("first", "签约失败通知");
            json.put("toUser", sf.getPatient());
            json.put("represented",sf.getPatient());//被代理人
            json.put("doctor", StringUtils.isEmpty(sf.getDoctor()) ? sf.getDoctorHealth() : sf.getDoctor());
            json.put("doctorName", StringUtils.isEmpty(sf.getDoctor()) ? sf.getDoctorHealthName() : sf.getDoctorName());
            json.put("date", DateUtil.dateToStrShort(new Date()));
            json.put("content", sf.getName() + "，您好！您与 " + (StringUtils.isEmpty(sf.getDoctor()) ? sf.getDoctorHealthName() : sf.getDoctorName()) + " 医生建立家庭医生签约关系失败，请查看！");
            json.put("remark", "您好，签约家庭医生失败通知");

            if (StringUtils.isNotBlank(sf.getOpenid())) {
                // 添加到发送队列
                PushMsgTask.getInstance().putWxMsg(access_token, 2, sf.getOpenid(), sf.getName(), json);
            } else {
                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(p.getCode());
                Patient member = (Patient) j.get("member");
                if (StringUtils.isNotBlank(member.getOpenid())) {
                    //String first = (String) json.get("first");
                    json.remove("first");
                    json.put("first", weiXinOpenIdUtils.getTitleMes(p, j.getInt("relation"), p.getName()));
                    PushMsgTask.getInstance().putWxMsg(access_token, 2, member.getOpenid(), p.getName(), json);
                }
            }


            result.put("status", 2);
            return result;
        }

        // 患者标签设置
        if (!(labelInfoService.setPatientLabels(p.getCode(), p.getIdcard(),
                p.getName(), healthLabel, disease, customLabel, sf.getDoctor(), caller) == 1)) {
            throw new Exception("patient sign label settting error:" + p.getIdcard());
        }

        // 推送消息消息给微信端
        if (type == 1) {
            Doctor doc = doctorDao.findByCode(StringUtils.isNotEmpty(doctor) ? sf.getDoctorHealth() : sf.getDoctor());
            Hospital hos = hospitalDao.findByCode(doc.getHospital());

            String content = sf.getName() + "，您好！祝贺您，成功签约" + doc.getName() + "医生团队，您已可以享受家庭医生所带来的无微不至的健康保健服务。" +
                    "为了给您提供更好的服务，请尽快到" + (hos != null ? hos.getName() : "") + "社区（地址：" +
                    (hos != null ? hos.getAddress() : "") + "）缴费。";
            // 同意签约
            JSONObject json = new JSONObject();
            json.put("first", "签约成功通知");
            json.put("toUser", sf.getPatient());
            json.put("represented",sf.getPatient());//被代理人
            json.put("doctor", doc.getCode());
            json.put("doctorName", doc.getName());
            json.put("date", DateUtil.dateToStrShort(new Date()));
            json.put("content", content);
            json.put("remark", ""); //您好，您成功签约家庭医生
            // 添加到发送队列
            if (StringUtils.isNotBlank(sf.getOpenid())) {
                PushMsgTask.getInstance().putWxMsg(access_token, 1, sf.getOpenid(), sf.getName(), json);
            } else {
                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(p.getCode());
                Patient member = (Patient) j.get("member");
                if (StringUtils.isNotBlank(member.getOpenid())) {
                    //String first = (String) json.get("first");
                    json.remove("first");
                    json.put("first", weiXinOpenIdUtils.getTitleMes(p, j.getInt("relation"), p.getName()));
                    PushMsgTask.getInstance().putWxMsg(access_token, 1, member.getOpenid(), p.getName(), json);
                }
            }


            new Thread(new SignUploadTask(sf.getCode())).start();
            JSONObject participants = new JSONObject();
            participants.put(sf.getPatient(), 0);
            if (StringUtils.equals(sf.getDoctor(), sf.getDoctorHealth())) {//全科和建管同一个人
                participants.put(sf.getDoctor(), 0);
            } else {//全科和建管不同一个人
                participants.put(sf.getDoctorHealth(), 0);
                participants.put(sf.getDoctor(), 1);
            }
            Patient patient = patientDao.findByCode(sf.getPatient());
            //创建医生会话讨论组
            JSONObject sessionObj = ImUtill.createSession(participants, ImUtill.SESSION_TYPE_MUC, patient.getName(), patient.getCode() + "_" + sf.getTeamCode() + "_" + 2);
            if (sessionObj.getInt("status") == -1) {
                throw new RuntimeException(sessionObj.getString("message"));
            }
            ImUtill.sendImMsg(doc.getCode(), doc.getName(), patient.getCode() + "_" + sf.getTeamCode() + "_" + 2, "0", "家庭医生签约成功！", "1");
        }
        result.put("status", 1);
        BusinessLogs.info(BusinessLogs.BusinessType.sign, caller, sf.getPatient(), new JSONObject(sf));
        return result;
    }

    /**
     * 处理解约申请
     *
     * @param patient 患者标识
     * @param type    处理类型：1同意，2拒绝
     * @param reason  解约原因
     * @return
     */
    public int handleSurrender(String access_token, long msgid, String patient, int type, String reason) throws Exception {
        if (type != 1 && type != 2) {
            return -1;
        }
        SignFamily sf = signFamilyDao.findByPatientCodeStatus(patient, 2);
        if (sf == null) {
            return 0;
        }
        // 更新消息状态为已处理
        if (msgid > 0) {
            Message message = messageDao.findOne(msgid);
            message.setRead(0);
            message.setOver("0");
        }
        if (type == 1) {
            // 设置家庭签约疾病无效
            if (!patientDiseaseService.updatePatientDisease(patient, "")) {
                throw new Exception("patient's disease update failed");
            }
            // 将签约状态改为已解约
            sf.setReason(reason);
            sf.setStatus(-3);
            sf.setApplyUnsignDate(new Date());
            //signFamilyDao.handleSurrender(reason, patient);
            //设置患者所在团队失效
            doctorTeamDao.deleteTeam(sf.getTeamCode());
            //设置团队成员失效
            doctorTeamDoctor.deleteMember(sf.getTeamCode());
            //把患者移除健康管理师和全科医生的晃患者管理
            doctorPatientGroupInfoDao.deleteByPatient(patient);
            //结束患者家庭签约咨询
            consultTeamDao.updateStatusByPatient(patient);

            // 推送消息消息给微信端
            JSONObject json = new JSONObject();
            json.put("first", "解约申请通知");
            json.put("toUser", sf.getPatient());
            json.put("represented",sf.getPatient());//被代理人
            json.put("date", DateUtil.getStringDateShort());
            json.put("doctor", sf.getDoctor());
            json.put("doctorName", sf.getDoctorName());
            json.put("orgName", sf.getHospitalName());
            json.put("remark", sf.getName() + "，您好！您的签约医生已同意您的解约申请，解约已生效。");

            if (StringUtils.isNotBlank(sf.getOpenid())) {
                // 添加到发送队列
                PushMsgTask.getInstance().putWxMsg(access_token, 5, sf.getOpenid(), sf.getName(), json);
            }
//            else {
//                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(patient);
//                Patient member = (Patient) j.get("member");
//                if (StringUtils.isNotBlank(member.getOpenid())) {
//                    String first = (String) json.get("first");
//                    json.remove("first");
//                    Patient p = patientDao.findByCode(patient);
//                    json.put("first", weiXinOpenIdUtils.getTitleMes(p, j.getInt("relation"), p.getName()));
//                    PushMsgTask.getInstance().putWxMsg(access_token, 5, member.getOpenid(), member.getName(), json);
//                }
//            }
            //发送代理人
            JSONArray jsonArray = weiXinOpenIdUtils.getAgentOpenId(sf.getPatient(),sf.getOpenid());
            if(jsonArray!=null&&jsonArray.length()>0){
                Patient p = patientDao.findByCode(patient);
                for (int i = 0;i<jsonArray.length();i++){
                    JSONObject j  = jsonArray.getJSONObject(i);
                    Patient member = (Patient) j.get("member");
                    JSONObject data = json;
                    data.remove("toUser");
                    data.put("toUser",member.getCode());
                    //String first = (String) json.get("first");
                    data.remove("first");
                    data.put("first",weiXinOpenIdUtils.getTitleMes(p,j.getInt("relation"),p.getName()));
                    PushMsgTask.getInstance().putWxMsg(access_token, 5, member.getOpenid(), p.getName(), data);
                }
            }
        } else {
            // 更新状态为正常
            signFamilyDao.refuseSurrender(patient);
            // 拒绝解约,推送消息消息给微信端
            JSONObject json = new JSONObject();
            json.put("first", "解约申请通知");
            json.put("toUser", sf.getPatient());
            json.put("represented",sf.getPatient());//被代理人
            json.put("date", DateUtil.getStringDateShort());
            json.put("doctor", sf.getDoctor());
            json.put("doctorName", sf.getDoctorName());
            json.put("orgName", sf.getHospitalName());
            json.put("remark", sf.getName() + "，您好！您的签约医生拒绝您的解约申请，解约失败。");

            if (StringUtils.isNotBlank(sf.getOpenid())) {
                // 添加到发送队列
                PushMsgTask.getInstance().putWxMsg(access_token, 5, sf.getOpenid(), sf.getName(), json);
            }
//            else {
//                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(patient);
//                Patient member = (Patient) j.get("member");
//                if (StringUtils.isNotBlank(member.getOpenid())) {
//                    String first = (String) json.get("first");
//                    json.remove("first");
//                    Patient p = patientDao.findByCode(patient);
//                    json.put("first", weiXinOpenIdUtils.getTitleMes(p, j.getInt("relation"), member.getName()));
//                    PushMsgTask.getInstance().putWxMsg(access_token, 5, member.getOpenid(), member.getName(), json);
//                }
//            }
            //发送代理人
            JSONArray jsonArray = weiXinOpenIdUtils.getAgentOpenId(sf.getPatient(),sf.getOpenid());
            if(jsonArray!=null&&jsonArray.length()>0){
                Patient p = patientDao.findByCode(patient);
                for (int i = 0;i<jsonArray.length();i++){
                    JSONObject j  = jsonArray.getJSONObject(i);
                    Patient member = (Patient) j.get("member");
                    JSONObject data = json;
                    data.remove("toUser");
                    data.put("toUser",member.getCode());
                    //String first = (String) json.get("first");
                    data.remove("first");
                    data.put("first",weiXinOpenIdUtils.getTitleMes(p,j.getInt("relation"),p.getName()));
                    PushMsgTask.getInstance().putWxMsg(access_token, 5, member.getOpenid(), p.getName(), data);
                }
            }

        }
        return 1;
    }

    /**
     * 查询医生的签约消息
     *
     * @param doctor   医生标识
     * @param id
     * @param pagesize 分页大小
     * @return
     */
    public Page<Message> findMessageByDoctor(String doctor, long id, int pagesize) {
        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.DESC, "id");
//        sort.and(new Sort(Direction.DESC,"read"));
//        sort.and(new Sort(Direction.DESC,"czrq"));

        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize, sort);
        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        filters.put("receiver", new SearchFilter("receiver", Operator.EQ, doctor));
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.LT, id));
        }
        // 只查询未处理的消息
        filters.put("type", new SearchFilter("type", Operator.EQ, 1));
        filters.put("over", new SearchFilter("over", Operator.EQ, 1));
        filters.put("read", new SearchFilter("read", Operator.EQ, 1));
        Specification<Message> spec = DynamicSpecifications.bySearchFilter(filters.values(), Message.class);
        return messageDao.findAll(spec, pageRequest);
    }

    /**
     * 查询已签约总数
     *
     * @param doctor
     * @return
     */
    public int countAmountSigned(String doctor) {
        return signFamilyDao.countAmountSignedByDoctor(doctor);
    }

    /**
     * 查询待签约总数
     *
     * @param doctor
     * @return
     */
    public int countAmountUnsign(String doctor) {
        return signFamilyDao.countAmountUnsignByDoctor(doctor);
    }


    public List<?> amountPatients(String uid) {
        return null;
    }

    public SignFamily getFamilyContractByIdcard(String idCard) {
        return signFamilyDao.findByIdcard(idCard);

    }

    public SignFamily getFamilyContractByMobile(String mobile) {
        return signFamilyDao.findByMobile(mobile);
    }

    /**
     * 生成签约标识
     *
     * @param doctor 医生标识
     * @return
     */
    private String createSignCode(String doctor, String hospital) {
        // 获取当前年份
        String year = DateUtil.getStringDate(DateUtil.YY);
        Hospital hospital1 = hospitalDao.findByCode(hospital);
        Integer amount = 0;
        SignFamilyCode wlyySignFamilyCode = wlyySignFamilyCodeDao.findByOrgCodeAndYear(hospital, year);
        if (wlyySignFamilyCode != null) {
            amount = wlyySignFamilyCode.getSequence() + 1;
            wlyySignFamilyCode.setSequence(amount);
            wlyySignFamilyCode.setModifyTime(new Date());
        } else {
            //创建序列
            amount = 1;
            SignFamilyCode wlyySignFamilyCodeTemp = new SignFamilyCode();
            wlyySignFamilyCodeTemp.setModifyTime(new Date());
            wlyySignFamilyCodeTemp.setOrgCode(hospital1.getCode());
            wlyySignFamilyCodeTemp.setOrgName(hospital1.getName());
            wlyySignFamilyCodeTemp.setYear(year);
            wlyySignFamilyCodeTemp.setSequence(1);
            wlyySignFamilyCodeDao.save(wlyySignFamilyCodeTemp);
        }

        return year + hospital1.getRoadCode() + hospital1.getCenterSite() + "Y" + StringUtils.leftPad(String.valueOf(amount + 1), 5, "0");
    }

    public SignFamily findBySanshiPatient(String code) {

        return signFamilyDao.findSanshiSignByPatient(code);
    }

    public SignFamily findByFamilySignPatient(String code) {

        return signFamilyDao.findFamilySignByPatient(code);
    }

    public SignFamily findByJiatingPatient(String code) {

        return signFamilyDao.findByjiatingPatientYes(code);
    }

    /**
     * 查询患者已签约信息
     *
     * @param code
     * @return
     */
    public SignFamily findBySsPatient(String code) {
        return signFamilyDao.findBySsPatient(code);
    }

    public List<Map<String, Object>> getDoctorsByhospitalNoPage(String hospital, String name, Integer type) {
        String sql = "select * from wlyy_doctor where 1=1 and del=1 and iscertified=1 and status=1 ";
        List<Object> params = new ArrayList<Object>();
        if (StringUtils.isNoneEmpty(hospital)) {
            sql += " and hospital =? ";
            params.add(hospital);
        }
        if (StringUtils.isNoneEmpty(name)) {
            sql += " and name like ? ";
            params.add("%" + name + "%");
        }
        if (type != null && type > 0) {
            sql += " and level =? ";
            params.add(type);
        }
        return jdbcTemplate.queryForList(sql, params.toArray());
    }

    public Map<String, Object> getSanshiSignByPatientCode(String patientCode) {
        Map<String, Object> map = new HashMap<>();
        SignFamily signFamily = signFamilyDao.findBySanshiPatient(patientCode);
        //判斷之前有没有三师签约
        if (signFamily != null) {
            map.put("hasSanshi", "true");
            //得到团队的专科医生
            DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findSanshiByTeamAndType(signFamily.getTeamCode(), 1);
            map.put("zkCode", doctorTeamMember.getMemberCode());
            map.put("zkName", doctorTeamMember.getName());
            //得到团队的全科医生
            doctorTeamMember = doctorTeamDoctor.findSanshiByTeamAndType(signFamily.getTeamCode(), 2);
            map.put("qkCode", doctorTeamMember.getMemberCode());
            map.put("qkName", doctorTeamMember.getName());
            //得到团队的健康管理医生
            doctorTeamMember = doctorTeamDoctor.findSanshiByTeamAndType(signFamily.getTeamCode(), 3);
            map.put("glsCode", doctorTeamMember.getMemberCode());
            map.put("glsName", doctorTeamMember.getName());
            //得到之前病人得的病
            Patient pa = patientDao.findByCode(patientCode);
            map.put("disease", pa.getDisease());
        } else {
            map.put("hasSanshi", "false");
        }
        return map;
    }

    public SignFamily findByPatientYes(String id) {
        return signFamilyDao.findByjiatingPatient(id);
    }

    public SignFamily findBySanshiPatientYes(String id) {
        return signFamilyDao.findBySanshiPatientYes(id);
    }

    /**
     * 根据身份证号查找病人的三师签约信息
     *
     * @param idCard
     * @return
     */
    public JSONObject getSanshiSingInfoByPatientIdCard(String idCard) throws Exception {
        JSONObject result = new JSONObject();
        SignFamily sign = signFamilyDao.findByPatientSanshiSignInfo(idCard);
        SignFamily signFamily = signFamilyDao.findByPatientFamilySignInfo(idCard);

        Patient p = patientDao.findByIdcard(idCard);

        //if (p == null) {
        //    result.put("signStatus", "0");
        //    result.put("msg", "病人未注册");
        //    return result;
        //}
        if (signFamily != null) {
            result.put("signStatus", "2");
            result.put("msg", "病人已申请过家庭签约!");
            return result;
        }

        if (sign != null) {
            List<DoctorTeamMember> members = doctorTeamDoctor.findByTeamAndDel(sign.getTeamCode(), "1");

            if (members == null) {
                throw new Exception("签约团队信息有误!");
            }

            //三师签约医生信息
            for (DoctorTeamMember member : members) {
                if (member.getType() == 1) {
                    result.put("majorDoctor", member.getMemberCode());
                    result.put("majorDoctorName", member.getName());
                } else if (member.getType() == 2) {
                    Doctor doctor = doctorDao.findByCode(member.getMemberCode());
                    result.put("hospital", doctor.getHospital());
                    result.put("doctor", member.getMemberCode());
                    result.put("doctorName", member.getName());
                } else if (member.getType() == 3) {
                    result.put("healthDoctor", member.getMemberCode());
                    result.put("healthDoctorName", member.getName());
                }
            }

            // 查询患者疾病
            List<PatientDisease> diseases = patientDiseaseDao.findByPatientSsDisease(p.getCode());

            if (diseases != null && diseases.size() > 0) {
                JSONArray disArray = new JSONArray();

                for (PatientDisease dis : diseases) {
                    disArray.put(new JSONObject(dis));
                }

                result.put("diseases", disArray);
            } else {
                result.put("diseases", "");
            }

            result.put("signStatus", "1");

        } else {
            result.put("signStatus", "3");
        }

        if (p != null) {
            JSONObject pJson = new JSONObject(p);
            if (pJson.has("password")) {
                pJson.remove("password");
            }
            if (pJson.has("salt")) {
                pJson.remove("salt");
            }
            result.put("patient", pJson);
        }

        return result;
    }

    public JSONArray getSignDoctorMessage(String patientCode) {
        JSONArray jsonArray = new JSONArray();
        //找出患者的三师签约信息
        SignFamily signFamily = signFamilyDao.findSanshiSignByPatient(patientCode);
        Patient patient = patientDao.findByCode(patientCode);
        if (signFamily != null) {
            //得到三师签约的服务团队
            List<Doctor> doctors = doctorDao.findSanshiDoctorByTeam(signFamily.getTeamCode());
            for (Doctor doctor : doctors) {
                JSONObject jo = new JSONObject();
                jo.put("code", doctor.getCode());//医生code
                jo.put("sex", doctor.getSex());//医生性别  1男，2女）
                jo.put("name", doctor.getName());//医生名称
                jo.put("photo", doctor.getPhoto());//医生头像
                jo.put("hosptialName", doctor.getHospitalName());//所属机构名称
                jo.put("level", doctor.getLevel());//医生等级1专科医生，2全科医生，3健康管理师
                jo.put("signType", "1");//签约类别 1是三师 2是家庭
                jo.put("signStatus", signFamily.getStatus());//签约状态 0待签约，1已签约 2待解约
                jo.put("jobName", doctor.getJobName());//职称
                jo.put("disease", patient.getDisease());//0健康，1高血压，2糖尿病，3高血压+糖尿病
                if (signFamily.getStatus() == 0) {
                    jo.put("sqDate", DateUtil.dateToStrShort(signFamily.getPatientApplyDate()));//申请时间
                } else if (signFamily.getStatus() == 1) {
                    jo.put("qyDate", DateUtil.dateToStrShort(signFamily.getBegin()));//签约时间
                    jo.put("endDate", DateUtil.dateToStrShort(signFamily.getEnd()));//结束时间
                } else if (signFamily.getStatus() == 2) {
                    jo.put("qyDate", DateUtil.dateToStrShort(signFamily.getPatientApplyUnsignDate()));//申请解约时间
                    jo.put("endDate", DateUtil.dateToStrShort(signFamily.getEnd()));//结束时间
                }
                jsonArray.put(jo);
            }
        }
        //得到家庭签约
        SignFamily jtSignFamily = signFamilyDao.findFamilySignByPatient(patientCode);

        if (jtSignFamily != null) {
            //家庭签约只找全科医生
            Doctor doctor = doctorDao.findByCode(jtSignFamily.getDoctor());
            Doctor doctorHealth = doctorDao.findByCode(jtSignFamily.getDoctorHealth());
            if (doctor != null) {
                JSONObject jo = new JSONObject();
                jo.put("code", doctor.getCode());
                jo.put("sex", doctor.getSex());
                jo.put("name", doctor.getName());
                jo.put("photo", doctor.getPhoto());
                jo.put("hosptialName", doctor.getHospitalName());
                jo.put("level", doctor.getLevel());
                jo.put("signType", "2");//2是家庭
                jo.put("signStatus", jtSignFamily.getStatus());
                jo.put("jobName", doctor.getJobName());
                jo.put("disease", patient.getDisease());//0健康，1高血压，2糖尿病，3高血压+糖尿病
                if (jtSignFamily.getStatus() == 0) {
                    jo.put("sqDate", DateUtil.dateToStrShort(jtSignFamily.getPatientApplyDate()));//申请时间
                } else {
                    jo.put("qyDate", DateUtil.dateToStrShort(jtSignFamily.getBegin()));//签约时间
                    jo.put("endDate", DateUtil.dateToStrShort(jtSignFamily.getEnd()));//结束时间
                }
                jsonArray.put(jo);
            }
            if (doctorHealth != null) {
                JSONObject jo = new JSONObject();
                jo.put("code", doctorHealth.getCode());
                jo.put("sex", doctorHealth.getSex());
                jo.put("name", doctorHealth.getName());
                jo.put("photo", doctorHealth.getPhoto());
                jo.put("hosptialName", doctorHealth.getHospitalName());
                jo.put("level", doctorHealth.getLevel());
                jo.put("signType", "2");//2是家庭
                jo.put("signStatus", jtSignFamily.getStatus());
                jo.put("jobName", doctorHealth.getJobName());
                jo.put("disease", patient.getDisease());//0健康，1高血压，2糖尿病，3高血压+糖尿病
                if (jtSignFamily.getStatus() == 0) {
                    jo.put("sqDate", DateUtil.dateToStrShort(jtSignFamily.getPatientApplyDate()));//申请时间
                } else {
                    jo.put("qyDate", DateUtil.dateToStrShort(jtSignFamily.getBegin()));//签约时间
                    jo.put("endDate", DateUtil.dateToStrShort(jtSignFamily.getEnd()));//结束时间
                }
                jsonArray.put(jo);
            }
        }
        return jsonArray;
    }

    public SignFamily getPatientSign(String patient) {
        return signFamilyDao.findByPatient(patient);
    }

    public SignFamily getssPatientSign(String invitePatientCode) {
        return signFamilyDao.findBySsPatient(invitePatientCode);
    }


    /**
     * 患者家庭签约收费类型更新
     *
     * @param expensesType
     * @param patient
     * @return
     */
    public boolean updateExpensesType(String expensesType, String patient) {
        return signFamilyDao.updateExpensesType(expensesType, patient) > 0;
    }

    public boolean updateSignStatus(String patientCard) {
        // 判断患者有没有家庭签约
        SignFamily sf = signFamilyDao.findByPatientStatus(patientCard, 0);
        if (sf != null) {
            sf.setStatus(-1);
        }
        return true;
    }

    public String produceSignAdminTeamCode() {
        StringBuffer sf = new StringBuffer();
        StringBuffer sf1 = new StringBuffer();
        Long size = 0L;
        //找出家庭签约中团队code是空的
        List<SignFamily> signFamilys = signFamilyDao.findBySignTypeAndTeamCode();
        sf.append("家庭签约中团队code是空的数据数:" + signFamilys.size());
        for (SignFamily signFamily : signFamilys) {
            //得到签约中的全科医生的团队
            String doctorCode = signFamily.getDoctor();
            Long id = doctorAdminTeamDao.findIdByLeaderCode(doctorCode);
            if (id != null && id > 0) {
                size++;
                signFamily.setAdminTeamId(id);
            } else {
                sf1.append(",找不到医生所属的团队,医生code:" + doctorCode);
            }
        }
        sf.append(",填充团队的签约数据数:" + size);
        sf.append(sf1);
        return sf.toString();
    }

    /**
     * 分配健管师
     *
     * @param patient      患者code
     * @param healthDoctor 健康管理师code
     * @return
     */
    public JSONObject updateSignInfo(String patient, String healthDoctor, String doctor, String expensesType, String loginUser) throws Exception{
        JSONObject result = new JSONObject();
        Patient p = patientDao.findByCode(patient);

        if (p == null) {
            result.put("status", -1);
            result.put("msg", "居民不存在");
            return result;
        }

        List<JSONObject> wxMessages = new ArrayList<>();

        SignFamily signFamily = signFamilyDao.findByjiatingPatientYes(patient);

        if (signFamily == null) {
            result.put("status", -1);
            result.put("msg", "居民不存在家庭签约");
            return result;
        }

        if (StringUtils.isNotEmpty(healthDoctor)) {
            Doctor docHealth = doctorDao.findByCode(healthDoctor);
            if (docHealth == null) {
                result.put("status", -2);
                result.put("msg", "医生不存在");
                return result;
            }
            String oldDoctorHealthName = signFamily.getDoctorHealthName();
            if (StringUtils.isNotEmpty(signFamily.getDoctorHealth())) {
                //判断患者对旧的健管师是否存在健康咨询
                ConsultTeam consultTeam = consultTeamDao.findByParientCodeAndSignTypeAndDoctor(patient, signFamily.getDoctorHealth(), 2);
                if (consultTeam != null) {
                    result.put("status", -1);
                    result.put("msg", "与当前健管师有未结束的咨询");
                    return result;
                }
                try {
                    if (signFamily.getDoctorHealth().equals(signFamily.getDoctor())) {
                        ImUtill.deleteMucUser(healthDoctor, "", patient + "_" + signFamily.getTeamCode() + "_2");
                    } else {
                        ImUtill.deleteMucUser(healthDoctor, signFamily.getDoctorHealth(), patient + "_" + signFamily.getTeamCode() + "_2");
                    }

                } catch (Exception e) {
                    result.put("status", -1);
                    result.put("msg", e.getMessage());
                    return result;
                }
                DoctorTeamMember teamMember = doctorTeamDoctor.findMemberByTeamAndCode(signFamily.getTeamCode(), signFamily.getDoctorHealth());

                if (teamMember != null) {
                    teamMember.setDel("0");
                    teamMember.setCzrq(new Date());
                    doctorTeamDoctor.save(teamMember);
                }

                JSONObject data = new JSONObject();
                data.put("toUser", patient);
                data.put("represented",patient);//被代理人
                data.put("doctor", docHealth.getCode());
                data.put("doctorName", docHealth.getName());
                data.put("first", p.getName() + "，您好！您签约团队的健康管理师已变更，您的新健管师信息如下：");
                data.put("keyword3", "家庭医生-健康管理师");
                data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
                data.put("keyword1", docHealth.getName());
                if (StringUtils.isEmpty(signFamily.getDoctor()) || docHealth.getCode().equals(signFamily.getDoctor())) {
                    data.put("remark", docHealth.getName() + "医生将继续为您提供优质健康服务");
                } else {
                    data.put("remark", docHealth.getName() + "医生将继续为您提供优质健康服务");
                }
                wxMessages.add(data);
            } else {
                JSONObject data = new JSONObject();
                data.put("toUser", patient);
                data.put("represented",patient);//被代理人
                data.put("doctor", docHealth.getCode());
                data.put("doctorName", docHealth.getName());
                data.put("first", p.getName() + "，您好！您的签约团队已为您新增一位健康管理师，医生信息如下：");
                data.put("keyword3", "家庭医生-健康管理师");
                data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
                data.put("keyword1", docHealth.getName());
                if (StringUtils.isEmpty(signFamily.getDoctor()) || docHealth.getCode().equals(signFamily.getDoctor())) {
                    data.put("remark", docHealth.getName() + "医生将继续为您提供优质健康服务");
                } else {
                    data.put("remark", docHealth.getName() + "医生与" + signFamily.getDoctorName() + "医生一道，为您提供优质健康服务");
                }
                wxMessages.add(data);
                try {
                    ImUtill.deleteMucUser(docHealth.getCode(), "", patient + "_" + signFamily.getTeamCode() + "_2");
                } catch (Exception e) {
                    result.put("status", -1);
                    result.put("msg", e.getMessage());
                    return result;
                }
            }
            // 新增团队信息
            if (StringUtils.isNotEmpty(signFamily.getTeamCode())) {
                DoctorTeamMember newTeamMember = new DoctorTeamMember();

                newTeamMember.setCode(getCode());
                newTeamMember.setMemberCode(docHealth.getCode());
                newTeamMember.setName(docHealth.getName());
                newTeamMember.setTeam(signFamily.getTeamCode());
                newTeamMember.setDel("1");
                newTeamMember.setSignType("2");
                newTeamMember.setType(3);
                newTeamMember.setCzrq(new Date());

                doctorTeamDoctor.save(newTeamMember);
            }

            signFamily.setDoctorHealth(docHealth.getCode());
            signFamily.setDoctorHealthName(docHealth.getName());
            signFamily.setCzrq(new Date());
        }

        if (StringUtils.isNotEmpty(doctor)) {
            Doctor docQk = doctorDao.findByCode(doctor);
            if (docQk == null) {
                result.put("status", -2);
                result.put("msg", "医生不存在");
                return result;
            }
            //判断患者对旧的健管师是否存在健康咨询
            ConsultTeam consultTeam = consultTeamDao.findByParientCodeAndSignTypeAndDoctor(patient, signFamily.getDoctor(), 2);
            if (consultTeam != null) {
                result.put("status", -1);
                result.put("msg", "与当前健管师有未结束的咨询");
                return result;
            }
            String oldDoctorName = signFamily.getDoctorName();
            if (StringUtils.isNotEmpty(signFamily.getDoctor())) {
                DoctorTeamMember teamMember = doctorTeamDoctor.findMemberByTeamAndQkCode(signFamily.getTeamCode(), signFamily.getDoctor());
                try {
                    ImUtill.deleteMucUser(doctor, signFamily.getDoctor(), patient + "_" + signFamily.getTeamCode() + "_2");
                } catch (Exception e) {
                    result.put("status", -1);
                    result.put("msg", e.getMessage());
                    return result;
                }
                if (teamMember != null) {
                    teamMember.setDel("0");
                    teamMember.setCzrq(new Date());
                    doctorTeamDoctor.save(teamMember);
                }
            }
            // 新增团队信息
            if (StringUtils.isNotEmpty(signFamily.getTeamCode())) {
                DoctorTeamMember newTeamMember = new DoctorTeamMember();

                newTeamMember.setCode(getCode());
                newTeamMember.setMemberCode(docQk.getCode());
                newTeamMember.setName(docQk.getName());
                newTeamMember.setTeam(signFamily.getTeamCode());
                newTeamMember.setDel("1");
                newTeamMember.setSignType("2");
                newTeamMember.setType(2);
                newTeamMember.setCzrq(new Date());

                doctorTeamDoctor.save(newTeamMember);
            }

            signFamily.setDoctor(docQk.getCode());
            signFamily.setDoctorName(docQk.getName());
            signFamily.setCzrq(new Date());

            JSONObject data = new JSONObject();
            data.put("toUser", patient);
            data.put("represented",patient);//被代理人
            data.put("doctor", docQk.getCode());
            data.put("doctorName", docQk.getName());
            data.put("first", p.getName() + "，您好！您签约团队的全科医生已变更，您的新全科医生信息如下：");
            data.put("keyword3", "家庭医生-全科医生");
            data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
            data.put("keyword1", docQk.getName());
            if (StringUtils.isEmpty(signFamily.getDoctorHealth()) || signFamily.getDoctor().equals(signFamily.getDoctorHealth())) {
                data.put("remark", docQk.getName() + "医生将专门为您提供优质健康服务");
            } else {
                data.put("remark", docQk.getName() + "医生将继续为您提供优质健康服务");
            }
            wxMessages.add(data);
        }

        if (StringUtils.isNotEmpty(expensesType)) {
            if (StringUtils.isNotEmpty(signFamily.getMedicalInsuranceNum())) {
                result.put("status", -3);
                result.put("msg", "数据已上传社保，不能修改补贴类型");
                return result;
            } else {
                signFamily.setExpensesType(expensesType);
            }
        }

        result.put("status", 1);
        result.put("msg", "更新成功");

        for (JSONObject msg : wxMessages) {

            if (StringUtils.isNotBlank(p.getOpenid())) {
                PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, p.getOpenid(), p.getName(), msg);
            }
//            else {
//                //如果自己没有绑定,则发给家人
//                JSONObject j = weiXinOpenIdUtils.getFamilyOpenId(p.getCode());
//                Patient member = (Patient) j.get("member");
//                if (StringUtils.isNotBlank(member.getOpenid())) {
//                    String first = (String) msg.get("first");
//                    msg.remove("first");
//
//                    try {
//                        msg.put("first", weiXinOpenIdUtils.getTitleMes(p, j.getInt("relation"), member.getName()));
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, member.getOpenid(), member.getName(), msg);
//                }
//            }
            //发送代理人
            JSONArray jsonArray = weiXinOpenIdUtils.getAgentOpenId(p.getCode(),p.getOpenid());
            if(jsonArray!=null&&jsonArray.length()>0){
                for (int i = 0;i<jsonArray.length();i++){
                    JSONObject j  = jsonArray.getJSONObject(i);
                    Patient member = (Patient) j.get("member");
                    JSONObject data = msg;
                    data.remove("toUser");
                    data.put("toUser",member.getCode());
                    String first = (String) data.get("first");
                    data.remove("first");
                    data.put("first",weiXinOpenIdUtils.getTitleMes(p,j.getInt("relation"),p.getName()));
                    PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, member.getOpenid(), p.getName(), data);
                }
            }

        }
        OperatorLog operatorLog = new OperatorLog();
        operatorLog.setCreateTime(new Date());
        operatorLog.setMethod("/doctor/family_contract/sign_info_update");
        operatorLog.setMethodName("签约信息变更");
        operatorLog.setCreateUser(loginUser);
        JSONObject jo = new JSONObject();
        jo.put("patient", patient);
        jo.put("healthDoctor", healthDoctor);
        jo.put("expensesType", expensesType);
        jo.put("doctor", doctor);
        operatorLog.setParams(jo.toString());
        operatorLogDao.save(operatorLog);
        return result;
    }

    public JSONObject findByParamsWithDoctor(String doctorCode, String teamCode, String params, int level) throws Exception {
        JSONObject returnMap = new JSONObject();
        String addressSql = "select a.signcode,a.name,a.address,a.code,a.hasopenid,a.idcard,a.photo from( SELECT " +
                "  sf.CODE signcode, " +
                "  p.photo photo, " +
                "  p.name name, " +
                "  p.address address, " +
                "  p.code code, " +
                "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                "  p.idcard idcard " +
                " FROM " +
                " wlyy_sign_family sf " +
                " JOIN wlyy_patient p ON sf.patient = p.CODE " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                // " and sf.doctor = ? " +
                " and sf.admin_team_code = ? " +
                " AND ( " + (level == 2 ? "sf.doctor =?" : "sf.doctor_health =? ") + ") ) a where 1=1";
        if (!org.springframework.util.StringUtils.isEmpty(params)) {
            addressSql += " AND a.address like '%" + params + "%'";
        }
        List<Map<String, Object>> datas = jdbcTemplate.queryForList(addressSql, teamCode, doctorCode);
        if (datas != null && datas.size() > 0) {
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : datas) {
                JSONObject jo = new JSONObject();
                jo.put("signcode", map.get("signcode"));
                jo.put("name", map.get("name"));
                jo.put("photo", map.get("photo"));
                jo.put("address", map.get("address"));
                jo.put("code", map.get("code"));
                jo.put("hasopenid", map.get("hasopenid"));
                jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                jsonArray.put(jo);
            }
            returnMap.put("address", jsonArray);
        }
        String patientNameSql = "select a.signcode,a.name,a.address,a.code,a.hasopenid,a.idcard,a.photo from( SELECT " +
                "  sf.CODE signcode, " +
                "  p.name name, " +
                "  p.photo photo, " +
                "  p.address address, " +
                "  p.code code, " +
                "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                "  p.idcard idcard " +
                " FROM " +
                " wlyy_sign_family sf " +
                " JOIN wlyy_patient p ON sf.patient = p.CODE " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                //" and sf.doctor = ? " +
                " and sf.admin_team_code = ? " +
                " AND ( " + (level == 2 ? "sf.doctor =?" : "sf.doctor_health =? ") + ") ) a where 1=1";

        if (!org.springframework.util.StringUtils.isEmpty(params)) {
            patientNameSql += " AND a.name like '%" + params + "%'";
        }
        datas = jdbcTemplate.queryForList(patientNameSql, teamCode, doctorCode);
        if (datas != null && datas.size() > 0) {
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : datas) {
                JSONObject jo = new JSONObject();
                jo.put("signcode", map.get("signcode"));
                jo.put("name", map.get("name"));
                jo.put("photo", map.get("photo"));
                jo.put("code", map.get("code"));
                jo.put("hasopenid", map.get("hasopenid"));
                jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                jsonArray.put(jo);
            }
            returnMap.put("name", jsonArray);
        }
        return returnMap;
    }

    public JSONObject findNoHealthSignFamilyHealthByParams(String doctorCode, String teamCode, String params) throws Exception {
        JSONObject returnMap = new JSONObject();
        String addressSql = "select a.signcode,a.name,a.address,a.code,a.hasopenid,a.idcard,a.photo from( SELECT " +
                "  sf.CODE signcode, " +
                "  p.photo photo, " +
                "  p.name name, " +
                "  p.address address, " +
                "  p.code code, " +
                "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                "  p.idcard idcard " +
                " FROM " +
                " wlyy_sign_family sf " +
                " JOIN wlyy_patient p ON sf.patient = p.CODE " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                // " and sf.doctor = ? " +
                " and sf.admin_team_code = ? " +
                " AND ( sf.doctor_health is null or sf.doctor_health ='' ) ) a where 1=1";
        if (!org.springframework.util.StringUtils.isEmpty(params)) {
            addressSql += " AND a.address like '%" + params + "%'";
        }
        List<Map<String, Object>> datas = jdbcTemplate.queryForList(addressSql, teamCode);
        if (datas != null && datas.size() > 0) {
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : datas) {
                JSONObject jo = new JSONObject();
                jo.put("signcode", map.get("signcode"));
                jo.put("name", map.get("name"));
                jo.put("photo", map.get("photo"));
                jo.put("address", map.get("address"));
                jo.put("code", map.get("code"));
                jo.put("hasopenid", map.get("hasopenid"));
                jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                jsonArray.put(jo);
            }
            returnMap.put("address", jsonArray);
        }
        String patientNameSql = "select a.signcode,a.name,a.address,a.code,a.hasopenid,a.idcard,a.photo from( SELECT " +
                "  sf.CODE signcode, " +
                "  p.name name, " +
                "  p.photo photo, " +
                "  p.address address, " +
                "  p.code code, " +
                "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                "  p.idcard idcard " +
                " FROM " +
                " wlyy_sign_family sf " +
                " JOIN wlyy_patient p ON sf.patient = p.CODE " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                //" and sf.doctor = ? " +
                " and sf.admin_team_code = ? " +
                " AND ( sf.doctor_health is null or sf.doctor_health ='' ) ) a where 1=1";

        if (!org.springframework.util.StringUtils.isEmpty(params)) {
            patientNameSql += " AND a.name like '%" + params + "%'";
        }
        datas = jdbcTemplate.queryForList(patientNameSql, teamCode);
        if (datas != null && datas.size() > 0) {
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : datas) {
                JSONObject jo = new JSONObject();
                jo.put("signcode", map.get("signcode"));
                jo.put("name", map.get("name"));
                jo.put("photo", map.get("photo"));
                jo.put("code", map.get("code"));
                jo.put("hasopenid", map.get("hasopenid"));
                jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                jsonArray.put(jo);
            }
            returnMap.put("name", jsonArray);
        }
        return returnMap;
    }

    public JSONObject findNoHealthSignFamilyHealth(String doctorCode, String labelType, String patientName, Long teamCode) throws Exception {
        JSONObject returnMap = new JSONObject();
        //健康管理师
        String sql = "SELECT " +
                "  sf. CODE signcode, " +
                "  p.photo photo, " +
                "  p.name name, " +
                "  p.code code, " +
                "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                "  sp.id labelid, " +
                "  CASE WHEN sp.label_name is null THEN '未标注' WHEN sp.label_name='' THEN '未标注' else sp.label_name END labelname, " +
                "  sp.label_type labeltype, " +
                "  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.label_type = ? AND sp.`status` = 1 " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf. STATUS > 0 " +
                // " and sf.doctor = ? " +
                " and sf.admin_team_code = ? " +
                " AND ( sf.doctor_health is null or sf.doctor_health ='' ) ";
        List<Map<String, Object>> datas = null;
        //查找居民
        datas = jdbcTemplate.queryForList(sql, labelType, teamCode);

        //根据类别查找标签
        List<SignPatientLabel> s = labelDao.findByLabelTypeAndStatusAndTeamCode(labelType, 1, teamCode);
        if (s != null && s.size() > 0) {
            for (SignPatientLabel one : s) {
                returnMap.put(one.getLabelName(), new JSONArray());
            }
            if (datas != null && datas.size() > 0) {
                for (Map<String, Object> map : datas) {
                    JSONObject jo = new JSONObject();
                    jo.put("signcode", map.get("signcode"));
                    jo.put("name", map.get("name"));
                    jo.put("photo", map.get("photo"));
                    jo.put("code", map.get("code"));
                    jo.put("hasopenid", map.get("hasopenid"));
                    jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                    jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                    JSONArray jr = new JSONArray();
                    if (returnMap.has(map.get("labelname").toString())) {
                        jr = returnMap.getJSONArray(map.get("labelname").toString());
                    }
                    jr.put(jo);
                    returnMap.put(map.get("labelname").toString(), jr);
                }
            }
        }
        return returnMap;
    }

    /**
     * 查询居民的所有签约
     *
     * @param patient
     * @return
     */
    public List<SignFamily> findAllSignByPatient(String patient) {
        return signFamilyDao.findAllSignByPatient(patient);
    }

    public List<SignFamily> findNoHealthSignFamilyNum(long teamCode) {
        return signFamilyDao.findNoHealthSignFamilyNum(teamCode);
    }

    /**
     * 获取未分配健管师关注公众号人数
     *
     * @param teamCode
     * @return
     * @throws Exception
     */
    public int findNoHealthSignFamilyFocusNum(Long teamCode) throws Exception {
        String sql = "select count(distinct patient) count from wlyy_sign_family where admin_team_code = ? and doctor_health is null and status > 0 and length(trim(ifnull(openid,''))) > 1";
        List<Map<String, Object>> count = jdbcTemplate.queryForList(sql, 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 patient
     * @param doctor
     * @return
     */
    public JSONObject isPatientAndDoctorExistSign(String patient, String doctor) {
        JSONObject result = new JSONObject();
        SignFamily familySign = signFamilyDao.findFamilySignByPatient(patient);
        SignFamily sanshiSign = signFamilyDao.findSanshiSignByPatient(patient);

        if (familySign != null) {
            if (doctor.equals(StringUtils.isEmpty(familySign.getDoctor()) ? "" : familySign.getDoctor()) ||
                    doctor.equals(StringUtils.isEmpty(familySign.getDoctorHealth()) ? "" : familySign.getDoctorHealth())) {
                if (familySign.getStatus() == 0) {
                    result.put("status", "0");
                    result.put("msg", "已申请家庭签约");
                } else {
                    result.put("status", "1");
                    result.put("msg", "已有家庭签约");
                }
                return result;
            }
        }
        if (sanshiSign != null) {
            if (doctor.equals(StringUtils.isEmpty(sanshiSign.getDoctor()) ? "" : sanshiSign.getDoctor()) ||
                    doctor.equals(StringUtils.isEmpty(sanshiSign.getDoctorHealth()) ? "" : sanshiSign.getDoctorHealth())) {
                result.put("status", "2");
                result.put("msg", "已有三师签约");
                return result;
            }
        }

        result.put("status", "-1");
        result.put("msg", "无签约关系");

        return result;
    }

    /**
     * 判断医生与居民是否可签约
     *
     * @param patient
     * @param doctor
     * @return
     */
    public JSONObject isPatientAndDoctorCanSign(String patient, String doctor) {
        JSONObject result = new JSONObject();
        Doctor doc = doctorDao.findByCode(doctor);
        SignFamily familySign = signFamilyDao.findFamilySignByPatient(patient);
        SignFamily sanshiSign = signFamilyDao.findSanshiSignByPatient(patient);

        if (familySign != null) {
            if (familySign.getStatus() == 0) {
                result.put("status", "0");
                result.put("msg", "已申请签约，不可签约");
            } else {
                result.put("status", "-1");
                result.put("msg", "因已签约家庭医生，不可签约");
            }

            return result;
        }
        if (sanshiSign != null) {
            if (doc.getLevel() == 2) {
                if (!doctor.equals(StringUtils.isEmpty(sanshiSign.getDoctor()) ? "" : sanshiSign.getDoctor())) {
                    result.put("status", "-2");
                    result.put("msg", "因签约对象不含签约三师中全科，不可签约");
                    return result;
                }
            } else {
                List<AdminTeam> teams = adminTeamService.findDoctorsTeams(doctor, sanshiSign.getDoctor());
                if (teams == null || teams.size() < 1) {
                    result.put("status", "-3");
                    result.put("msg", "因签约对象不与签约三师中全科在同一团队，不可签约");
                } else {
                    result.put("status", "1");
                    result.put("msg", "可签约");
                    result.put("team", teams);
                }
                return result;
            }
        }

        result.put("status", "1");
        result.put("msg", "可签约");

        return result;
    }

    /**
     * 查询患者对应医生
     *
     * @param patient
     * @return
     */
    public JSONObject getPatientDoctors(String patient, String doctor) {
        JSONObject result = new JSONObject();
        Map<String, JSONObject> docMap = new HashMap<>();
        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
        SignFamily jtSign = signFamilyDao.findSignByPatient(patient, 2);

        if (ssSign != null) {
            DoctorTeamMember member = doctorTeamDoctor.findSanshiByTeamAndType(ssSign.getTeamCode(), 1);
            if (member != null) {
                Doctor doc = doctorDao.findByCode(member.getMemberCode());
                JSONObject json = new JSONObject(doc);
                if (json.has("password")) {
                    json.remove("password");
                }
                if (json.has("salt")) {
                    json.remove("salt");
                }
                result.put("dutyDoctor", json);
            } else {
                result.put("dutyDoctor", "");
            }
            List<Doctor> doctors = adminTeamService.getMembers(ssSign.getAdminTeamId());

            if (doctors != null) {
                for (Doctor doc : doctors) {
                    if (doc.getCode().equals(doctor)) {
                        continue;
                    }
                    JSONObject json = new JSONObject(doc);
                    if (json.has("password")) {
                        json.remove("password");
                    }
                    if (json.has("salt")) {
                        json.remove("salt");
                    }
                    docMap.put(doc.getCode(), json);
                }
            }
        }
        if (jtSign != null) {
            List<Doctor> doctors = adminTeamService.getMembers(jtSign.getAdminTeamId());
            if (doctors != null) {
                for (Doctor doc : doctors) {
                    if (doc.getCode().equals(doctor)) {
                        continue;
                    }
                    JSONObject json = new JSONObject(doc);
                    if (json.has("password")) {
                        json.remove("password");
                    }
                    if (json.has("salt")) {
                        json.remove("salt");
                    }
                    docMap.put(doc.getCode(), json);
                }
            }
        }

        if (docMap.size() > 0) {
            result.put("teamDoctors", new JSONArray(docMap.values()));
        } else {
            result.put("teamDoctors", new JSONArray());
        }

        return result;
    }

    /**
     * 根据会话信息拉取对应的人员信息
     *
     * @param sessionId
     * @return
     */
    public JSONObject getTeamDoctors(String sessionId, String doctor) {
        String infos[] = sessionId.split("_");
        String patient = infos[0];
        JSONObject result = new JSONObject();
        Map<String, JSONObject> docMap = new HashMap<>();
        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
//        SignFamily jtSign = signFamilyDao.findByTeamCode(infos[1]);
        SignFamily jtSign = getSignFamilyBySessionId(sessionId,infos[0]);
        if (ssSign != null) {
            DoctorTeamMember member = doctorTeamDoctor.findSanshiByTeamAndType(ssSign.getTeamCode(), 1);
            if (member != null) {
                Doctor doc = doctorDao.findByCode(member.getMemberCode());
                JSONObject json = new JSONObject(doc);
                if (json.has("password")) {
                    json.remove("password");
                }
                if (json.has("salt")) {
                    json.remove("salt");
                }
                result.put("dutyDoctor", json);
            } else {
                result.put("dutyDoctor", "");
            }
            List<Doctor> doctors = adminTeamService.getMembers(ssSign.getAdminTeamId());

            if (doctors != null) {
                for (Doctor doc : doctors) {
                    if (doc.getCode().equals(doctor)) {
                        continue;
                    }
                    JSONObject json = new JSONObject(doc);
                    if (json.has("password")) {
                        json.remove("password");
                    }
                    if (json.has("salt")) {
                        json.remove("salt");
                    }
                    docMap.put(doc.getCode(), json);
                }
            }
        }
        if (jtSign != null) {
            List<Doctor> doctors = adminTeamService.getMembers(jtSign.getAdminTeamId());
            if (doctors != null) {
                for (Doctor doc : doctors) {
                    if (doc.getCode().equals(doctor)) {
                        continue;
                    }
                    JSONObject json = new JSONObject(doc);
                    if (json.has("password")) {
                        json.remove("password");
                    }
                    if (json.has("salt")) {
                        json.remove("salt");
                    }
                    docMap.put(doc.getCode(), json);
                }
            }
        }
        if (docMap.size() > 0) {
            result.put("teamDoctors", new JSONArray(docMap.values()));
        } else {
            result.put("teamDoctors", new JSONArray());
        }

        return result;
    }


    public JSONObject getPatientSignDoctorsByTeam(String sessionId) {
        String infos[] = sessionId.split("_");
        JSONObject result = new JSONObject();
        Map<String, JSONObject> docMap = new HashMap<>();
        SignFamily ssSign = signFamilyDao.findSignByPatient(infos[0], 1);
//        SignFamily jtSign = signFamilyDao.findByTeamCode(infos[1]);
        SignFamily jtSign = getSignFamilyBySessionId(sessionId,infos[0]);
        JSONObject ssArray = new JSONObject();
        JSONObject jtArray = new JSONObject();
        if (ssSign != null) {
            JSONObject qkDoc = new JSONObject();
            qkDoc.put("doctor", ssSign.getDoctor());
            qkDoc.put("doctorName", ssSign.getDoctorName());
            ssArray.put("doctor", qkDoc);
            JSONObject jgDoc = new JSONObject();
            jgDoc.put("doctor", ssSign.getDoctorHealth());
            jgDoc.put("doctorName", ssSign.getDoctorHealthName());
            ssArray.put("doctorHealth", jgDoc);
        }
        if (jtSign != null) {
            JSONObject qkDoc = new JSONObject();
            qkDoc.put("doctor", jtSign.getDoctor());
            qkDoc.put("doctorName", jtSign.getDoctorName());
            jtArray.put("doctor", qkDoc);
            JSONObject jgDoc = new JSONObject();
            jgDoc.put("doctor", jtSign.getDoctorHealth());
            jgDoc.put("doctorName", jtSign.getDoctorHealthName());
            jtArray.put("doctorHealth", jgDoc);
        }
        result.put("ssSign", ssArray);
        result.put("jtSign", jtArray);
        return result;
    }

    /**
     * 根据会话id查询 家庭签约信息
     * @param sessionId
     * @param patient
     * @return
     */
    public SignFamily getSignFamilyBySessionId(String sessionId,String patient){
        SignFamily signFamily = null;
        String sql = "select id from " + SystemConf.getInstance().getImDataBaseName() + ".topics where  session_id = '"+sessionId+"' order by create_time desc limit 0, 1";
        List<Map<String,Object>> list = jdbcTemplate.queryForList(sql);
        if(list!=null&&list.size()>0){
            String consultCode = list.get(0).get("id").toString();
            signFamily = signFamilyDao.findByPatient(patient);
            Consult consult = consultDao.findByCode(consultCode);
            if(signFamily==null||signFamily.getApplyDate().getTime()-consult.getCzrq().getTime()>0){
                signFamily = signFamilyDao.findOutTimeSigningByPatient(patient);
            }
        }
        return signFamily;
    }


    /**
     * 查询患者对应医生
     *
     * @param patient
     * @return
     */
    public JSONObject getPatientSignDoctors(String patient) {
        JSONObject result = new JSONObject();
        Map<String, JSONObject> docMap = new HashMap<>();
        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
        SignFamily jtSign = signFamilyDao.findSignByPatient(patient, 2);
        JSONObject ssArray = new JSONObject();
        JSONObject jtArray = new JSONObject();

        if (ssSign != null) {
            JSONObject qkDoc = new JSONObject();
            qkDoc.put("doctor", ssSign.getDoctor());
            qkDoc.put("doctorName", ssSign.getDoctorName());

            ssArray.put("doctor", qkDoc);

            JSONObject jgDoc = new JSONObject();
            jgDoc.put("doctor", ssSign.getDoctorHealth());
            jgDoc.put("doctorName", ssSign.getDoctorHealthName());

            ssArray.put("doctorHealth", jgDoc);
        }
        if (jtSign != null) {
            JSONObject qkDoc = new JSONObject();
            qkDoc.put("doctor", jtSign.getDoctor());
            qkDoc.put("doctorName", jtSign.getDoctorName());

            jtArray.put("doctor", qkDoc);

            JSONObject jgDoc = new JSONObject();
            jgDoc.put("doctor", jtSign.getDoctorHealth());
            jgDoc.put("doctorName", jtSign.getDoctorHealthName());

            jtArray.put("doctorHealth", jgDoc);
        }

        result.put("ssSign", ssArray);
        result.put("jtSign", jtArray);

        return result;
    }

    public Map<String, List<Patient>> getPatientByLevel(String doctorCode, Long team) {
        Map<String, List<Patient>> returnMap = new HashMap<>();
        Doctor doctor = doctorDao.findByCode(doctorCode);
        //判断当前用户是健康管理师还是全科
        if (doctor.getLevel() == 3) {
            //健康管理师
            List<Patient> jkgl = signFamilyDao.findByDoctorHealthPatient(doctorCode, team);
            returnMap.put("jk", jkgl);
        } else if (doctor.getLevel() == 2) {
            //全科医生
            List<Patient> qkys = signFamilyDao.findByDoctorPatient(doctorCode, team);
            returnMap.put("qk", qkys);
            //健康管理师
            List<Patient> jkgl = signFamilyDao.findByDoctorHealthPatient(doctorCode, team);
            returnMap.put("jk", jkgl);
        }
        return returnMap;
    }

    //根据姓名、地址、身份证搜索已分配健管师的居民
    public List getPatientByLable(String doctorCode, String filter, String level, Long team,int page,int pagesize) throws Exception {
        List list = new ArrayList();
        //判断当前用户是健康管理师还是全科
        List<Map<String, Object>> datas = null;
        if (level.equals("3")) {
            //健康管理师
            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.doctor_health = ? " +
                    " and sf.admin_team_code = ? " +
                    " 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;

            //查找居民
            datas = jdbcTemplate.queryForList(sql, doctorCode, team,"%"+filter+"%","%"+filter+"%","%"+filter+"%");
        } else if (level.equals("2")) {
            //全科
            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.doctor = ?  " +
                    " and sf.admin_team_code = ? " +
                    " 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;

            //查找居民
            datas = jdbcTemplate.queryForList(sql, doctorCode, team,"%"+filter+"%","%"+filter+"%","%"+filter+"%");

        } else {
            throw new Exception("参数错误！");
        }
        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;
    }

    public JSONObject getPatientByLable(String doctorCode, String labelType, String level, Long team) throws Exception {
        JSONObject returnMap = new JSONObject();
        //判断当前用户是健康管理师还是全科
        List<Map<String, Object>> datas = null;
        if (level.equals("3")) {
            //健康管理师
            String sql = "SELECT " +
                    "  sf. CODE signcode, " +
                    "  p.name name, " +
                    "  p.photo photo, " +
                    "  p.code code, " +
                    "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                    "  sp.id labelid, " +
                    " CASE WHEN sp.label_name is null THEN '未标注' WHEN sp.label_name='' THEN '未标注' else sp.label_name END labelname, " +
                    "  sp.label_type labeltype, " +
                    "  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.label_type = ? AND sp.`status` = 1 " +
                    " WHERE " +
                    " sf.type = 2 " +
                    " AND sf. STATUS > 0 " +
                    " and sf.doctor_health = ? " +
                    " and sf.admin_team_code = ? ";

            //查找居民
            datas = jdbcTemplate.queryForList(sql, labelType, doctorCode, team);
        } else if (level.equals("2")) {
            //全科
            String sql = "SELECT " +
                    "  sf. CODE signcode, " +
                    "  p.name name, " +
                    "  p.photo photo, " +
                    "  p.code code, " +
                    "  CASE WHEN p.openid is null THEN '0' WHEN p.openid='' THEN '0' else 1 END hasopenid, " +
                    "  sp.id labelid, " +
                    " CASE WHEN sp.label_name is null THEN '未标注' WHEN sp.label_name='' THEN '未标注' else sp.label_name END labelname, " +
                    "  sp.label_type labeltype, " +
                    "  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.label_type = ? AND sp.`status` = 1 " +
                    " WHERE " +
                    " sf.type = 2 " +
                    " AND sf. STATUS > 0 " +
                    " and  sf.doctor = ?  " +
                    " and sf.admin_team_code = ? ";

            //查找居民
            datas = jdbcTemplate.queryForList(sql, labelType, doctorCode, team);

        } else {
            throw new Exception("参数错误！");
        }
        //根据类别查找标签
        List<SignPatientLabel> s = labelDao.findByLabelTypeAndStatusAndTeamCode(labelType, 1, team);
        if (s != null && s.size() > 0) {
            for (SignPatientLabel one : s) {
                returnMap.put(one.getLabelName(), new JSONArray());
            }
            if (datas != null && datas.size() > 0) {
                for (Map<String, Object> map : datas) {
                    JSONObject jo = new JSONObject();
                    jo.put("signcode", map.get("signcode"));
                    jo.put("name", map.get("name"));
                    jo.put("photo", map.get("photo"));
                    jo.put("code", map.get("code"));
                    jo.put("hasopenid", map.get("hasopenid"));
                    jo.put("age", IdCardUtil.getAgeForIdcard(map.get("idcard").toString()));
                    jo.put("sex", IdCardUtil.getSexForIdcard_new(map.get("idcard").toString()));
                    //判断name是否为空 为空就是未标注
                    //把患者添加到对应的组
                    JSONArray jr = new JSONArray();
                    if (returnMap.has(map.get("labelname").toString())) {
                        jr = returnMap.getJSONArray(map.get("labelname").toString());
                    }
                    jr.put(jo);
                    returnMap.put(map.get("labelname").toString(), jr);
                }
            }
        }
        return returnMap;
    }


    public Integer findPatientCountByAdminTeam(String doctorCode, String teamCode) {
        String sql = "select count(sf.id) " +
                " FROM " +
                " wlyy_sign_family sf " +
                " WHERE " +
                " sf.type = 2 " +
                " AND sf.STATUS > 0 " +
                " AND ( sf.doctor = ? or sf.doctor_health=? )" +
                " AND sf.admin_team_code =?";
        Object[] parms = new Object[]{doctorCode, doctorCode, teamCode};
        Integer count = jdbcTemplate.queryForObject(sql, parms, Integer.class);
        return count;
    }


    /**
     * 查询医生与居民的团队
     *
     * @param patient
     * @param doctor
     * @return
     */
    public JSONObject getPatientAndDoctorTeams(String patient, String doctor) {
        JSONObject result = new JSONObject();
        SignFamily ssSign = signFamilyDao.findSignByPatient(patient, 1);
        SignFamily jtSign = signFamilyDao.findSignByPatient(patient, 2);

        if (ssSign != null && ssSign.getAdminTeamId() != null) {
            JSONObject ssTeam = new JSONObject();
            if (doctor.equals(ssSign.getDoctor()) || doctor.equals(ssSign.getDoctorHealth())) {
                ssTeam.put("hasSign", 1);
            } else {
                ssTeam.put("hasSign", 0);
            }

            AdminTeam team = adminTeamService.getTeam(ssSign.getAdminTeamId());

            if (team != null) {
                if (doctor.equals(team.getLeaderCode())) {
                    ssTeam.put("isLeader", 1);
                } else {
                    ssTeam.put("isLeader", 0);
                }

                ssTeam.put("team", new JSONObject(team));
                if (ssTeam.getInt("hasSign") == 1 || ssTeam.getInt("isLeader") == 1) {
                    result.put("ssTeam", ssTeam);
                }
            }
        }

        if (jtSign != null) {
            JSONObject jtTeam = new JSONObject();
            if (doctor.equals(jtSign.getDoctor()) || doctor.equals(jtSign.getDoctorHealth())) {
                jtTeam.put("hasSign", 1);
            } else {
                jtTeam.put("hasSign", 0);
            }

            AdminTeam team = adminTeamService.getTeam(jtSign.getAdminTeamId());

            if (team != null) {
                if (doctor.equals(team.getLeaderCode())) {
                    jtTeam.put("isLeader", 1);
                } else {
                    jtTeam.put("isLeader", 0);
                }

                jtTeam.put("team", new JSONObject(team));
                if (jtTeam.getInt("hasSign") == 1 || jtTeam.getInt("isLeader") == 1) {
                    result.put("jtTeam", jtTeam);
                }
            }
        }

        if (result.has("jtTeam") || result.has("ssTeam")) {
            result.put("hasSign", 1);
        } else {
            result.put("hasSign", 0);
        }

        return result;
    }


    /**
     * 续签申请
     *
     * @param doctor  签约医生
     * @param patient 居民code
     * @return
     */
    @Transactional
    public int signRenew(String doctor,String healthDoctor, String patient, String reason) throws Exception {
        Patient p = patientDao.findByCode(patient);
        if (p == null) {
            return -1;
        }

//        List<SignFamilyRenew> sc = signFamilyRenewDao.findByIdcard(p.getIdcard());
//        //判断身份证号是否已签约
//        if (sc != null&&sc.size()>0) {
//            return -2;
//        }

        Doctor d = doctorDao.findByCode(doctor);
        Doctor hd = null;
        if(StringUtils.isNotBlank(healthDoctor)){
            hd = doctorDao.findByCode(healthDoctor);
        }

        if (d == null) {
            return -3;
        }
        Calendar cal = Calendar.getInstance();
        int year =cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;

        List<SignFamilyRenew> res = signFamilyRenewDao.findByDoctorAndPatientHossPost(patient,DateUtil.getSignYear()+"");
        if(res!=null&&res.size()>0){
            return -2;
        }

        SignFamilyRenew sf = new SignFamilyRenew();


        String sql = "";
        //判断是否有生效记录SQL
        sql ="SELECT t.doctor,t.team_code teamCode,t.admin_team_code adminTeamCode,t.mobile FROM wlyy_sign_family t WHERE t.patient ='" + patient + "' AND t.status>=0 AND t.expenses_status='1' AND t.sign_year ='"+(DateUtil.getSignYear()-1)+"'";

        List<Map<String,Object>> signs = jdbcTemplate.queryForList(sql);
        if(signs==null||signs.size()==0){
            return -4;
        }
        Map<String,Object> sign = signs.get(0);
        //判断续签医生是否一致
        if(doctor.equals(sign.get("doctor"))){
            //如果一致保存团队信息
            sf.setTeamCode((String)sign.get("teamCode"));
            Integer c=(Integer)sign.get("adminTeamCode");
            sf.setRenewFlag("1");
            sf.setAdminTeamId(c.longValue());
        }else {
            //如果不一致 查看医生团队
            sf.setRenewFlag("2");
//            String tcSql = "SELECT t.id FROM wlyy_admin_team t WHERE t.leader_code ='"+doctor+"'";
//            List<Map<String ,Object>> ids = jdbcTemplate.queryForList(tcSql);
//            if(ids!=null&&ids.size()>0){
//                Integer id =  (Integer)ids.get(0).get("id");
//                Long lid = id.longValue();
//                sf.setAdminTeamId(lid);
//            }else{
//                //未找到团队信息
//                return -5;
//            }
            //新建咨询团队组逻辑
            DoctorTeam team = new DoctorTeam();
            String code = getCode();
            team.setCode(code);
            team.setCzrq(new Date());
            team.setDel("1");
            team.setSignType("2");
            //判断是否有健康管理师
            if(hd!=null&&StringUtils.isNotBlank(hd.getName())){
                team.setName(d.getName()+","+hd.getName()+","+p.getName());
                //新建健康管理师
                DoctorTeamMember hdmb = new DoctorTeamMember();
                hdmb.setName(hd.getName());
                hdmb.setMemberCode(healthDoctor);
                hdmb.setCode(getCode());
                hdmb.setDel("1");
                hdmb.setCzrq(new Date());
                hdmb.setTeam(code);
                hdmb.setType(3);
                hdmb.setSignType("2");
                doctorTeamDoctor.save(hdmb);
            }else{
                team.setName(d.getName()+","+p.getName());
            }
            //新建医生成员
            DoctorTeamMember dmb = new DoctorTeamMember();
            dmb.setName(d.getName());
            dmb.setMemberCode(doctor);
            dmb.setCode(getCode());
            dmb.setDel("1");
            dmb.setCzrq(new Date());
            dmb.setTeam(code);
            dmb.setType(d.getLevel());
            dmb.setSignType("2");

            //新建病人
            DoctorTeamMember pmb = new DoctorTeamMember();
            pmb.setName(p.getName());
            pmb.setMemberCode(patient);
            pmb.setCode(getCode());
            pmb.setDel("1");
            pmb.setCzrq(new Date());
            pmb.setTeam(code);
            pmb.setType(5);
            pmb.setSignType("2");

            doctorTeamDoctor.save(dmb);
            doctorTeamDoctor.save(pmb);
            doctorTeamDao.save(team);
            //关联新团队
            sf.setTeamCode(code);
        }
        sf.setCode(getCode());
        sf.setCzrq(new Date());
        sf.setPatientApplyDate(new Date());

        if(d!=null){
            sf.setDoctor(doctor);
            sf.setDoctorName(d.getName());
            sf.setSignDoctorCode(doctor);
            sf.setSignDoctorName(d.getName());
        }

        if(hd!=null){
            sf.setDoctorHealth(healthDoctor);
            sf.setDoctorHealthName(hd.getName());
        }
        sf.setMobile((String)sign.get("mobile"));
        sf.setName(p.getName());
        sf.setIdcard(p.getIdcard());
        sf.setOpenid(p.getOpenid());
        sf.setPatient(patient);
        sf.setHospital(d.getHospital());
        sf.setHospitalName(d.getHospitalName());
        sf.setSsc(p.getSsc());
        sf.setStatus(0);//0为初始状态
        sf.setType(2);// 设置为家庭签约
        sf.setSignType("1");//用户申请
        sf.setSignSource("2");//签约来源【1 社区签约 2 移动签约】
        //******************扣费接口**********************/
        sf.setExpensesStatus("0");   //扣费状态 【0未扣费 1已扣费 2已退费】

        sf.setSignYear(DateUtil.getSignYear()+"");
        sf.setIsValid(0);
        sf.setBegin(DateUtil.stringToDate(DateUtil.getSignYear()+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));
        sf.setEnd(DateUtil.stringToDate(DateUtil.getSignYear()+1+"-06-30 23:59:59","yyyy-MM-dd HH:mmm:ss"));
        //设置转签原因
        if(StringUtils.isNotBlank(reason)){
            sf.setRenewChangeReason(reason);
        }

        SignFamilyRenew temp = signFamilyRenewDao.save(sf);

        if (temp != null) {
            // 添加签约消息
            Message message = new Message();
            message.setCzrq(new Date());
            message.setCreateTime(new Date());
            message.setContent("您有一条新的家庭医生续签申请!");
            message.setRead(1);//设置未读
            message.setReceiver(doctor);//设置接受医生的code
            message.setSender(patient);//设置发送的用户
            message.setSenderName(p.getName());
            message.setCode(getCode());
            message.setSenderPhoto(p.getPhoto());
            message.setTitle("家庭续签申请");
            message.setType(1);//家庭签约信息
            message.setReadonly(1);//是否只读消息
            if("1".equals(sf.getRenewFlag())){
                message.setSignStatus("8");//续签
            }else{
                message.setSignStatus("9");//改签
            }

            message.setSex(p.getSex());
            message.setOver("1");//未处理
            message.setData(sf.getCode());
            messageDao.save(message);
            // 发送消息给医生
            JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(doctor);
            if (jsonObject.getString("status").equals("1")) {
                //如果在工作时间内就推送
                PushMsgTask.getInstance().put(doctor, MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.D_SW_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.家庭签约.name(), p.getName()+"申请与您续签家庭医生", patient);
            }
        }

        return 1;
    }

    /**
     * 续签申请(7月之后)
     *
     * @param doctor  签约医生
     * @param patient 居民code
     * @return
     */
    @Transactional
    public int signRenewOverdue(String doctor,String healthDoctor, String patient, String reason) throws Exception {
        Patient p = patientDao.findByCode(patient);
        if (p == null) {
            return -1;
        }

        Doctor d = doctorDao.findByCode(doctor);
        Doctor hd = null;
        if(StringUtils.isNotBlank(healthDoctor)){
            hd = doctorDao.findByCode(healthDoctor);
        }

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


        List<SignFamily> res = signFamilyDao.findByDoctorAndPatientHossPost(patient,DateUtil.getSignYear()+"");
        if(res!=null&&res.size()>0){
            return -2;
        }

        SignFamily sf = new SignFamily();

        Calendar cal = Calendar.getInstance();
        int year =cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;
        String sql  ="SELECT t.doctor,t.team_code teamCode,t.admin_team_code adminTeamCode,t.mobile FROM wlyy_sign_family t WHERE t.patient ='" + patient + "' AND t.status=-4 AND t.expenses_status='1' AND t.sign_year ='"+(year-1)+"'";


        List<Map<String,Object>> signs = jdbcTemplate.queryForList(sql);
        if(signs==null||signs.size()==0){
            return -4;
        }
        Map<String,Object> sign = signs.get(0);
        //判断续签医生是否一致
        if(doctor.equals(sign.get("doctor"))){
            //如果一致保存团队信息
            sf.setRenewFlag("1");
            sf.setTeamCode((String)sign.get("teamCode"));
            Integer c=(Integer)sign.get("adminTeamCode");
            sf.setAdminTeamId(c.longValue());
        }else {
            //如果不一致 查看医生团队
            sf.setRenewFlag("2");
//            String tcSql = "SELECT t.id FROM wlyy_admin_team t WHERE t.leader_code ='"+doctor+"'";
//            List<Map<String ,Object>> ids = jdbcTemplate.queryForList(tcSql);
//            if(ids!=null&&ids.size()>0){
//                Integer id =  (Integer)ids.get(0).get("id");
//                Long lid = id.longValue();
//                sf.setAdminTeamId(lid);
//            }else{
//                //未找到团队信息
//                return -5;
//            }
            //新建咨询团队组
            DoctorTeam team = new DoctorTeam();
            String code = getCode();
            team.setCode(code);
            team.setCzrq(new Date());
            team.setDel("1");
            team.setSignType("2");
            //判断是否有健康管理师
            if(hd!=null&&StringUtils.isNotBlank(hd.getName())){
                team.setName(d.getName()+","+hd.getName()+","+p.getName());
                //新建健康管理师
                DoctorTeamMember hdmb = new DoctorTeamMember();
                hdmb.setName(hd.getName());
                hdmb.setMemberCode(healthDoctor);
                hdmb.setCode(getCode());
                hdmb.setDel("1");
                hdmb.setCzrq(new Date());
                hdmb.setTeam(code);
                hdmb.setType(3);
                hdmb.setSignType("2");
                doctorTeamDoctor.save(hdmb);
            }else{
                team.setName(d.getName()+","+p.getName());
            }
            //新建医生成员
            DoctorTeamMember dmb = new DoctorTeamMember();
            dmb.setName(d.getName());
            dmb.setMemberCode(doctor);
            dmb.setCode(getCode());
            dmb.setDel("1");
            dmb.setCzrq(new Date());
            dmb.setTeam(code);
            dmb.setType(d.getLevel());
            dmb.setSignType("2");

            //新建病人
            DoctorTeamMember pmb = new DoctorTeamMember();
            pmb.setName(p.getName());
            pmb.setMemberCode(patient);
            pmb.setCode(getCode());
            pmb.setDel("1");
            pmb.setCzrq(new Date());
            pmb.setTeam(code);
            pmb.setType(5);
            pmb.setSignType("2");

            doctorTeamDoctor.save(dmb);
            doctorTeamDoctor.save(pmb);
            doctorTeamDao.save(team);
            //关联新团队
            sf.setTeamCode(code);
        }
        sf.setCode(getCode());
        sf.setCzrq(new Date());
        sf.setPatientApplyDate(new Date());

        if(d!=null){
            sf.setDoctor(doctor);
            sf.setDoctorName(d.getName());
            sf.setSignDoctorCode(doctor);
            sf.setSignDoctorName(d.getName());
        }

        if(hd!=null){
            sf.setDoctorHealth(healthDoctor);
            sf.setDoctorHealthName(hd.getName());
        }
        sf.setMobile((String)sign.get("mobile"));
        sf.setName(p.getName());
        sf.setIdcard(p.getIdcard());
        sf.setOpenid(p.getOpenid());
        sf.setPatient(patient);
        sf.setHospital(d.getHospital());
        sf.setHospitalName(d.getHospitalName());
        sf.setSsc(p.getSsc());
        sf.setStatus(0);//0为初始状态
        sf.setType(2);// 设置为家庭签约
        sf.setSignType("1");//用户申请
        sf.setSignSource("2");//签约来源【1 社区签约 2 移动签约】
        //******************扣费接口**********************/
        sf.setExpensesStatus("0");   //扣费状态 【0未扣费 1已扣费 2已退费】

        sf.setSignYear(year+"");

        sf.setBegin(DateUtil.stringToDate(DateUtil.getSignYear()+"-07-01 00:00:00","yyyy-MM-dd HH:mmm:ss"));
        sf.setEnd(DateUtil.stringToDate(DateUtil.getSignYear()+1+"-06-30 23:59:59","yyyy-MM-dd HH:mmm:ss"));

        if(StringUtils.isNotBlank(reason)){
            sf.setRenewChangeReason(reason);
        }
        SignFamily temp = signFamilyDao.save(sf);

        if (temp != null) {
            // 添加签约消息
            Message message = new Message();
            message.setCzrq(new Date());
            message.setCreateTime(new Date());
            message.setContent("您有一条新的家庭医生续签申请!");
            message.setRead(1);//设置未读
            message.setReceiver(doctor);//设置接受医生的code
            message.setSender(patient);//设置发送的用户
            message.setSenderName(p.getName());
            message.setCode(getCode());
            message.setSenderPhoto(p.getPhoto());
            message.setTitle("家庭续签申请");
            message.setType(1);//家庭签约信息
            message.setReadonly(1);//是否只读消息

            if("1".equals(sf.getRenewFlag())){
                message.setSignStatus("8");//续签
            }else{
                message.setSignStatus("9");//改签
            }
            //message.setSignStatus("1");//过期以后,变为1为签约
            message.setSex(p.getSex());
            message.setOver("1");//未处理
            message.setData(sf.getCode());
            messageDao.save(message);
            // 发送消息给医生
            JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(doctor);
            if (jsonObject.getString("status").equals("1")) {
                //如果在工作时间内就推送
                PushMsgTask.getInstance().put(doctor, MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.D_SW_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_SIGN_WEB.家庭签约.name(), p.getName()+"申请与您续签家庭医生", patient);
            }
        }

        return 1;
    }

    /**
     *
     * @param code
     * @return
     */
    public String getTeamName(String code){
        try{
            String sql = "SELECT t.name FROM wlyy_doctor_team t WHERE t.code ='"+code+"'";

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

            if(map!=null&&map.size()>0){
                return (String)map.get(0).get("name");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }


    public JSONArray getSignDoctorMessageOverDue(String patientCode) {
        JSONArray jsonArray = new JSONArray();
        //找出患者的三师签约信息
        Patient patient = patientDao.findByCode(patientCode);

        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);

        //得到家庭签约
        SignFamily jtSignFamily = signFamilyDao.findFamilySignByPatientOverDue(patientCode,(year-1)+"");

        if (jtSignFamily != null) {
            //家庭签约只找全科医生
            Doctor doctor = doctorDao.findByCode(jtSignFamily.getDoctor());
            Doctor doctorHealth = doctorDao.findByCode(jtSignFamily.getDoctorHealth());
            if (doctor != null) {
                JSONObject jo = new JSONObject();
                jo.put("code", doctor.getCode());
                jo.put("sex", doctor.getSex());
                jo.put("name", doctor.getName());
                jo.put("photo", doctor.getPhoto());
                jo.put("hosptialName", doctor.getHospitalName());
                jo.put("level", doctor.getLevel());
                jo.put("signType", "2");//三师签约
                jo.put("signStatus", jtSignFamily.getStatus());
                jo.put("jobName", doctor.getJobName());
                jo.put("disease", patient.getDisease());//0健康，1高血压，2糖尿病，3高血压+糖尿病
                if (jtSignFamily.getStatus() == 0) {
                    jo.put("sqDate", DateUtil.dateToStrShort(jtSignFamily.getPatientApplyDate()));//申请时间
                } else {
                    jo.put("qyDate", DateUtil.dateToStrShort(jtSignFamily.getBegin()));//签约时间
                    jo.put("endDate", DateUtil.dateToStrShort(jtSignFamily.getEnd()));//结束时间
                }
                jsonArray.put(jo);
            }
            if (doctorHealth != null) {
                JSONObject jo = new JSONObject();
                jo.put("code", doctorHealth.getCode());
                jo.put("sex", doctorHealth.getSex());
                jo.put("name", doctorHealth.getName());
                jo.put("photo", doctorHealth.getPhoto());
                jo.put("hosptialName", doctorHealth.getHospitalName());
                jo.put("level", doctorHealth.getLevel());
                jo.put("signType", "2");//三师签约
                jo.put("signStatus", jtSignFamily.getStatus());
                jo.put("jobName", doctorHealth.getJobName());
                jo.put("disease", patient.getDisease());//0健康，1高血压，2糖尿病，3高血压+糖尿病
                if (jtSignFamily.getStatus() == 0) {
                    jo.put("sqDate", DateUtil.dateToStrShort(jtSignFamily.getPatientApplyDate()));//申请时间
                } else {
                    jo.put("qyDate", DateUtil.dateToStrShort(jtSignFamily.getBegin()));//签约时间
                    jo.put("endDate", DateUtil.dateToStrShort(jtSignFamily.getEnd()));//结束时间
                }
                jsonArray.put(jo);
            }
        }
        return jsonArray;
    }

    /**
     * 存储同步纪委标识
     * @param idCard
     * @param signYear
     */
    public void setSignFamilyMapping(String signCode,String idCard,String signYear){
        SignFamilyMapping maping = new SignFamilyMapping();
        maping.setCode(signCode);
        maping.setCreateTime(new Date());
        maping.setIdcard(idCard);
        maping.setNeedUpdate("0");
        maping.setSignYear(signYear);
        //判断是否是预签约
        //判断规则:如果在4月份到7月份为预签约
        int month = DateUtil.getNowMonth();
        if(month>=4&&month<7){
            //预签约逻辑
            maping.setNeedUpload("0");
            maping.setNeedRenewUpload("1");
        }else{
            maping.setNeedUpload("1");
            maping.setNeedRenewUpload("0");
        }
        signFamilyMappingDao.save(maping);
    }

    public SignFamily findOutTimeSigningByPatient(String patient) {
        return signFamilyDao.findOutTimeSigningByPatient(patient);
    }

    public JSONObject getServerPatientList(Long teamCode){
        String serverSql="SELECT " +
                " d.`code` As labelCode, " +
                " d.`name` AS label " +
                " FROM " +
                " wlyy_sign_dict d " +
                " WHERE " +
                " d.type IN ('1', '2') " +
                " AND d. YEAR = '"+DateUtil.getSignYear()+"' " +
                " AND d.`code` NOT IN ( " +
                " SELECT " +
                "  LEFT ( " +
                "   d. CODE, " +
                "   (INSTR(d. CODE, '-') - 1) " +
                "  ) AS CODE " +
                " FROM " +
                "  wlyy_sign_dict d " +
                " WHERE " +
                "  d. CODE LIKE '%-%' " +
                " GROUP BY " +
                "  CODE " +
                ")";
        String patientSql =" SELECT " +
                " s.patient, " +
                " s.server_type AS serverType, " +
                " s.special_population AS specialPopulation, " +
                " s.sign_year " +
                " FROM " +
                " wlyy_sign_family s " +
                " WHERE " +
                " s.`status` >= 0 " +
                " AND s.server_type IS NOT NULL AND s.server_type <>'3' "+
                " AND s.admin_team_code =" +teamCode+
                " AND s.doctor_health IS NULL";
        List<Map<String,Object>> patientList = jdbcTemplate.queryForList(patientSql);

        JSONObject rs = new JSONObject();
        rs.put("count",(patientList!=null&&patientList.size()>0)?patientList.size():0);

        List<Map<String,Object>> serlist = jdbcTemplate.queryForList(serverSql);
        if(serlist!=null&&serlist.size()>0){
            if(patientList!=null){
                for(Map<String,Object> map :serlist){
                    String labelCode = (String)map.get("labelCode");
                    List<Map<String,String>> codes = new ArrayList<>();
                    Iterator iterator = patientList.iterator();
                    while(iterator.hasNext()){
                        Map<String,Object> p =  ( Map<String,Object>)iterator.next();
                        String serverType = p.get("serverType") ==null?"":((String)p.get("serverType"));
                        if(labelCode.indexOf("-")==-1){
                            if(labelCode.equals(serverType)){
                                Map<String,String> code = new HashMap<>();
                                code.put("code",(String)p.get("patient"));
                                codes.add(code);
                                iterator.remove();
                            }
                        }else{
                            String[] key = labelCode.split("-");
                            if(key[0].equals(serverType)){
                                Map<String,String> code = new HashMap<>();
                                code.put("code",(String)p.get("patient"));
                                codes.add(code);
                                iterator.remove();
                            }
                        }
                    }
                    map.put("codes",codes);
                    map.put("number",(codes!=null&&codes.size()>0)?codes.size():0);
                }
            }
        }

        rs.put("patients",serlist);
        return rs;
    }

    public JSONObject getServerPatientListNum(Long teamCode,String level, String oldDoctorCode){
        String serverSql="SELECT " +
                " d.`code` As labelCode, " +
                " d.`name` AS label " +
                " FROM " +
                " wlyy_sign_dict d " +
                " WHERE " +
                " d.type IN ('1', '2') " +
                " AND d. YEAR = '"+DateUtil.getSignYear()+"' " +
                " AND d.`code` NOT IN ( " +
                " SELECT " +
                "  LEFT ( " +
                "   d. CODE, " +
                "   (INSTR(d. CODE, '-') - 1) " +
                "  ) AS CODE " +
                " FROM " +
                "  wlyy_sign_dict d " +
                " WHERE " +
                "  d. CODE LIKE '%-%' " +
                " GROUP BY " +
                "  CODE " +
                ")";
        String patientSql =" SELECT " +
                " s.patient, " +
                " s.server_type AS serverType, " +
                " s.special_population AS specialPopulation, " +
                " s.sign_year " +
                " FROM " +
                " wlyy_sign_family s " +
                " WHERE " +
                " s.`status` >= 0 " +
                " AND s.server_type IS NOT NULL AND s.server_type <>'3' "+
                " AND s.admin_team_code =" +teamCode;
        //1查询全科,其他查询健管师
        if("2".equals(level)){
            patientSql =  patientSql+" AND s.doctor ='"+oldDoctorCode+"'";
        }else{
            patientSql =  patientSql+" AND s.doctor_health ='"+oldDoctorCode+"'";
        }
        List<Map<String,Object>> patientList = jdbcTemplate.queryForList(patientSql);

        JSONObject rs = new JSONObject();
        rs.put("count",(patientList!=null&&patientList.size()>0)?patientList.size():0);

        List<Map<String,Object>> serlist = jdbcTemplate.queryForList(serverSql);
        if(serlist!=null&&serlist.size()>0){
            if(patientList!=null){
                for(Map<String,Object> map :serlist){
                    String labelCode = (String)map.get("labelCode");
                    List<Map<String,String>> codes = new ArrayList<>();
                    Iterator iterator = patientList.iterator();
                    while(iterator.hasNext()){
                        Map<String,Object> p =  ( Map<String,Object>)iterator.next();
                        String serverType = p.get("serverType") ==null?"":((String)p.get("serverType"));
                        if(labelCode.indexOf("-")==-1){
                            if(labelCode.equals(serverType)){
                                Map<String,String> code = new HashMap<>();
                                code.put("code",(String)p.get("patient"));
                                codes.add(code);
                                iterator.remove();
                            }
                        }else{
                            String[] key = labelCode.split("-");
                            if(key[0].equals(serverType)){
                                Map<String,String> code = new HashMap<>();
                                code.put("code",(String)p.get("patient"));
                                codes.add(code);
                                iterator.remove();
                            }
                        }
                    }
                    map.put("codes",codes);
                    map.put("number",(codes!=null&&codes.size()>0)?codes.size():0);
                }
            }
        }

        rs.put("patients",serlist);
        return rs;
    }



    public List<Map<String,Object>> patientGroupByServerType(String doctor) {

        // 先根据server_type分组查找wlyy_sign_family表中该医生的签约的患者，然后wlyy_sign_dict left join 得到全部的类型

        String sql=" select sd.code labelCode,sd.name labelName,IFNULL(t.count,0) amount from wlyy_sign_dict sd  " +

                " left join " +

                " ( " +

                " SELECT " +

                "  sf.server_type type, " +

                "  sf.server_type_name name, " +

                "  count(id) count " +

                " FROM " +

                "  wlyy_sign_family sf " +

                " WHERE " +

                "  sf. STATUS > 0 " +

                " AND ( " +

                "  sf.doctor =? " +

                "  or sf.doctor_health =? " +

                " ) " +

                " group by sf.server_type " +

                " ) t " +

                " on sd.`code`=t.type " +

                " where  sd.id in (4,5,6,7,8,9,10,11,12)";



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

        return queryData;

    }

}
