package com.yihu.wlyy.web.doctor.sign;

import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import com.yihu.wlyy.aop.ObserverRequired;
import com.yihu.wlyy.entity.doctor.team.admin.AdminTeam;
import com.yihu.wlyy.entity.doctor.team.sign.SignPatientLabel;
import com.yihu.wlyy.entity.message.Message;
import com.yihu.wlyy.logs.BusinessLogs;
import com.yihu.wlyy.repository.doctor.SignPatientLabelDao;
import com.yihu.wlyy.service.app.account.PatientInfoService;
import com.yihu.wlyy.service.app.family.FamilyMemberService;
import com.yihu.wlyy.service.app.message.MessageService;
import com.yihu.wlyy.service.app.sign.PatientRemindService;
import com.yihu.wlyy.service.app.team.AdminTeamService;
import com.yihu.wlyy.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
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.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.service.app.sign.FamilyContractService;
import com.yihu.wlyy.service.common.account.DoctorService;
import com.yihu.wlyy.service.common.account.PatientService;
import com.yihu.wlyy.web.WeixinBaseController;
import springfox.documentation.spring.web.json.Json;

/**
 * 医生端：家庭签约控制类
 *
 * @author George
 */
@Controller
@RequestMapping(value = "/doctor/family_contract", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Api(description = "医生端-家庭签约")
public class DoctorFamilyContractController extends WeixinBaseController {

    @Autowired
    private FamilyContractService familyContractService;
    @Autowired
    private DoctorService doctorService;
    @Autowired
    private PatientService patientService;
    @Autowired
    PatientInfoService patientInfoService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    MessageService messageService;
    @Autowired
    PatientRemindService patientRemindService;
    @Autowired
    AdminTeamService teamService;
    @Autowired
    FamilyMemberService familyMemberService;
    @Autowired
    SignPatientLabelDao labelDao;

    /**
     * 根据姓名、地址、身份证搜索已分配的居民
     *
     * @param filter
     * @param teamCode
     * @param doctor   健管师编码
     * @param page
     * @param pagesize
     * @return
     */
    @RequestMapping(value = "getPatientByParams")
    @ResponseBody
    @ApiOperation("由姓名|地址|身份证号搜索团队内已分配健管的居民")
    public String getPatientByParams(@RequestParam String filter,
                                     @RequestParam String teamCode,
                                     @RequestParam String doctor,
                                     @RequestParam String level,
                                     @RequestParam int page,
                                     @RequestParam int pagesize) {
        try {
            if (StringUtils.isEmpty(filter)) {
                return error(-1, "搜索条件不能为空！");
            }
            if (StringUtils.isEmpty(teamCode)) {
                return error(-1, "团队不能为空！");
            }
            long team = Long.parseLong(teamCode);
//            level 医生身份
            List list = familyContractService.getPatientByLable(doctor, filter, level, team, page, pagesize);
            return write(200, "查询成功！", "data", list);
        } catch (Exception e) {
            error(e);
            return invalidUserException(e, -1, "查询失败！");
        }
    }

    /**
     * 分组查询已分配健管的居民的数量
     *
     * @param labelType
     * @param teamCode
     * @return
     */
    @RequestMapping(value = "getPatientByParamsNum")
    @ResponseBody
    public String getPatientByParamsNum(
            @RequestParam String labelType,
            @RequestParam String level,
            @RequestParam Long teamCode) {
        try {
            List listNum = new ArrayList();
            JSONObject list = familyContractService.getPatientByLable(getUID(), labelType, level, teamCode);
            List<SignPatientLabel> s = labelDao.findByLabelTypeAndStatusAndTeamCode(labelType, 1, teamCode);
            for (SignPatientLabel label : s) {
                Map map = new HashMap();
                String labelName = label.getLabelName();
                JSONArray jsonArray = list.getJSONArray(label.getLabelName());
                int length = jsonArray.length();
                map.put("label", labelName);
                map.put("number", length);
                listNum.add(map);
            }
            return write(200, "查询成功！", "data", listNum);
        } catch (Exception e) {
            error(e);
            return invalidUserException(e, -1, "查询失败");
        }
    }

    /**
     * 查看当前医生签约的居民
     */
    @RequestMapping(value = "getPatientByLevel")
    @ResponseBody
    public String getPatientByLevel(String doctorCode, Long team) {
        try {
            JSONObject returnJO = new JSONObject();
            Map<String, List<Patient>> list = familyContractService.getPatientByLevel(doctorCode, team);
            if (list != null && list.size() > 0) {
                for (Map.Entry<String, List<Patient>> entyr : list.entrySet()) {
                    JSONArray array = new JSONArray();
                    addList(returnJO, entyr.getValue(), array, entyr.getKey());
                }
            }
            return write(200, "签约数据加载成功！", "data", returnJO);
        } catch (Exception e) {
            error(e);
            return error(-1, "签约数据加载失败！");
        }
    }

    /**
     * 查看当前医生签约的居民
     */
    @RequestMapping(value = "getMobilePatient")
    @ResponseBody
    public String getMobilePatient(String mobile) {
        try {
            List<Patient> patients = patientService.findByMobile(mobile);
            return write(200, "获取数据成功！", "data", patients);
        } catch (Exception e) {
            error(e);
            return error(-1, "获取数据失败！");
        }
    }

    private void addList(JSONObject returnJO, List<Patient> pts, JSONArray array, String key) {
        if (pts != null && pts.size() > 0) {
            for (Patient sf : pts) {
                if (sf == null) {
                    continue;
                }
                JSONObject json = new JSONObject();
                json.put("id", sf.getId());
                // 签约患者标识
                json.put("code", sf.getCode());
                // 签约患者名称
                json.put("name", sf.getName());
                // 签约患者头像
                json.put("photo", sf.getPhoto());
                // 签约患者性别
                json.put("sex", sf.getSex());
                // 签约患者性别
                json.put("age", IdCardUtil.getAgeForIdcard(sf.getIdcard()));
                array.put(json);
            }
            returnJO.put(key, array);
        }
    }

    /**
     * 根据标签查看当前医生签约的居民  3 健康管理师  2是全科
     */
    @RequestMapping(value = "/getPatientByLable")
    @ResponseBody
    public String getPatientByLable(String labelType, String level, String doctorcode, Long team) {
        try {
            JSONObject list = familyContractService.getPatientByLable(doctorcode, labelType, level, team);
            return write(200, "查询成功", "data", list);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 根据标签查看当前医生签约的居民  3 健康管理师  2是全科    修改为未分组 未标注 参考doctor/patient_label_info/label_patient_amount
     */
    @RequestMapping(value = "/getPatientLables")
    @ResponseBody
    public String getPatientLables(String labelType, String level, String oldDoctorCode, Long teamCode) {
        try {
            //修改年度服务类型1.3.4需求
            if ("1".equals(labelType)) {
                JSONObject rs = familyContractService.getServerPatientListNum(teamCode, level, oldDoctorCode);
                return write(200, "查询成功！", "data", rs);
            }

            int count = 0;
            List listNum = new ArrayList();
            JSONObject list = familyContractService.getPatientByLable(oldDoctorCode, labelType, level, teamCode);

            List<SignPatientLabel> s = labelDao.findByLabelTypeAndStatusAndTeamCode(labelType, 1, teamCode);

            for (SignPatientLabel label : s) {
                Map map = new HashMap();
                String labelName = label.getLabelName();
                JSONArray jsonArray = list.getJSONArray(label.getLabelName());
                List codes = new ArrayList();

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject json = jsonArray.getJSONObject(i);
                    Map info = new HashMap();
                    String code = json.getString("code");
                    String name = json.getString("name");
                    info.put("code", code);
                    info.put("name", name);
                    codes.add(info);
                }
                int length = codes.size();
                map.put("label", labelName);
                map.put("codes", codes);
                map.put("number", length);
                listNum.add(map);
                count += length;
            }

            if (list.has("未标注")) {
                JSONArray noGroup = list.getJSONArray("未标注");
                List codes = new ArrayList();
                for (int i = 0; i < noGroup.length(); i++) {
                    JSONObject json = noGroup.getJSONObject(i);
                    Map info = new HashMap();
                    String code = json.getString("code");
                    String name = json.getString("name");
                    info.put("code", code);
                    info.put("name", name);
                    codes.add(info);
                }
                Map map = new HashMap();
                int size = noGroup.length();
                map.put("label", "未标注");
                map.put("codes", codes);
                map.put("number", size);
                listNum.add(map);
                count += size;
            }

            Map map = new HashMap();
            map.put("count", count);
            map.put("patients", listNum);
            return write(200, "查询成功", "data", map);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 医生签约患者列表查询接口
     *
     * @param type     0全部，1待签约，2已签约，3待解约，4已解约
     * @param id
     * @param pagesize 分页大小
     * @return
     */
    @RequestMapping(value = "list")
    @ResponseBody
    public String list(int type, long id, int pagesize) {
        try {
            JSONArray array = new JSONArray();
            Page<SignFamily> list = familyContractService.findSignByDoctor(type, id, pagesize);
            if (list != null) {
                for (SignFamily sf : list) {
                    if (sf == null) {
                        continue;
                    }
                    JSONObject json = new JSONObject();
                    json.put("id", sf.getId());
                    // 签约标识
                    json.put("code", sf.getCode());
                    // 签约医院名称
                    json.put("hospital_name", sf.getHospitalName());
                    // 签约医生姓名
                    json.put("doctor_name", sf.getDoctorName());
                    // 开始日期
                    json.put("begin", DateUtil.dateToStrShort(sf.getBegin()));
                    // 结束日期
                    json.put("end", DateUtil.dateToStrShort(sf.getEnd()));
                    // 签约状态(-1患者已取消，-2已拒绝，-3已解约，-4已到期，0待签约，1已签约，2患者申请取消签约，3医生申请取消签约
                    json.put("status", sf.getStatus());
                    array.put(json);
                }
            }
            return write(200, "签约数据加载成功！", "list", array);
        } catch (Exception e) {
            error(e);
            return error(-1, "签约数据加载失败！");
        }
    }

    /**
     * 校验是否有签约信息
     *
     * @param idcard
     * @return
     */
    @RequestMapping(value = "check")
    @ResponseBody
    public String checkSign(String idcard) {
        try {
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空！");
            }
            JSONObject json = new JSONObject();
            // 解密身份证号
            idcard = RSAUtils.getInstance(familyContractService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "请输入身份证号！");
            }
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号！");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号！");
            }

            Patient patient = patientService.findByIdcard(idcard);
            if (patient == null) {
                // 未签约
                json.put("sign", 2);
            } else {
                json = familyContractService.checkSign(patient);
                if (json == null) {
                    return error(-1, "签约验证异常！");
                }
            }
            return write(200, "签约验证成功！", "data", json);
        } catch (Exception e) {
            error(e);
            return error(-1, "签约验证异常！");
        }
    }

    /**
     * 手工代签约接口
     *
     * @param name       患者名称
     * @param idcard     身份证号
     * @param ssc        社保卡号
     * @param mobile     手机号
     * @param emerMobile 应急人手机号
     * @param images     图片URL，多图以逗号分隔
     * @param expenses   签约费用
     * @return
     */
    @RequestMapping(value = "agent")
    @ResponseBody
    @ObserverRequired
    public String agent(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String idcard,
            @RequestParam(required = false) String ssc,
            @RequestParam(required = false) String mobile,
            @RequestParam(required = false) String healthLabel,
            @RequestParam(required = false, defaultValue = "") String customLabel,
            @RequestParam(required = false, defaultValue = "") String disease,
            @RequestParam(required = false) String emerMobile,
            @RequestParam(required = false) String healthDoctor,
            @RequestParam(required = false) String healthDoctorName,
            @RequestParam(required = false) String images,
            @RequestParam(required = false, defaultValue = "0") String expenses,
            @RequestParam(required = false) String doctor,//全科医生code
            @RequestParam(required = false) String doctorName,//全科医生名字
            @RequestParam(required = false) String signDoctorCode,//簽約人code
            @RequestParam(required = false) String signDoctorName,//簽約人銘
            @RequestParam(required = false) String signDoctorLevel,//簽約人等级
            @RequestParam(required = false) long adminTeamCode, //行政团队
            @RequestParam(required = false) String sevId) {
        try {
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "请输入身份证号！");
            }
            if (StringUtils.isEmpty(healthDoctor) || StringUtils.isEmpty(healthDoctorName)) {
                return error(-1, "请选择健康管理师！");
            }
            // 解密身份证号
            idcard = RSAUtils.getInstance(familyContractService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号！");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号！");
            }

            if (StringUtils.isEmpty(name)) {
                return error(-1, "姓名不允许为空！");
            }
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空！");
            }
            if (StringUtils.isEmpty(ssc)) {
                return error(-1, "社保卡号不允许为空！");
            }
            if (StringUtils.isEmpty(healthLabel)) {
                return error(-1, "健康情况标签不能为空！");
            }
            if (adminTeamCode < 1) {
                return error(-1, "行政团队不能为空！");
            }
            int amount = familyContractService.hasSingStatus(idcard);
            if (amount > 0) {
                return error(-1, "该居民已签约了家庭医生！");
            }
            if (StringUtils.isNotEmpty(images)) {
                images = CommonUtil.copyTempImage(images);
            }
            /**modify by linz 2017年2月28日10:11:49**/
            //if (!org.springframework.util.StringUtils.isEmpty(mobile)) {
            //    Patient patient = patientService.findByMobile(mobile);
            //    if (patient != null && !StringUtils.equals(patient.getIdcard(), idcard)) {
            //        return error(-1, "该手机号已绑定其他身份证号！");
            //    }
            //}
            /**end**/
            Doctor cDoctor = doctorService.findDoctorByCode(getUID());

            SignFamily sf = familyContractService.agent(getAccessToken(), name, doctor, doctorName,
                    healthDoctor, healthDoctorName, cDoctor.getHospital(), cDoctor.getHospitalName(),
                    idcard, ssc, mobile, emerMobile, images, healthLabel, customLabel, disease, expenses, signDoctorCode, signDoctorName, signDoctorLevel, adminTeamCode, sevId);
            if (sf == null) {
                return error(-1, "代理签约失败！");
            } else {
                try {
                    Patient p = patientService.findByIdcard(idcard);
                    BusinessLogs.info(BusinessLogs.BusinessType.register, getUID(), p.getCode(), new JSONObject(p));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return success("代理签约成功！");
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "代理签约失败！");
        }
    }

    /**
     * 患者签约申请处理接口
     *
     * @param signType         是否有三师签约 1 否 2是
     * @param healthDoctor     健康管理师标识
     * @param healthDoctorName 健康管理师姓名
     * @param disease          疾病code
     * @param msgid            消息id
     * @param patientIDcard    患者身份证
     * @param type             处理类型：1同意，2拒绝
     * @param adminTeamCode    行政团队code
     * @return
     */
    @RequestMapping(value = "sign")
    @ResponseBody
    @ObserverRequired
    public String sign(
            @RequestParam(required = true, defaultValue = "1") String signType,
            @RequestParam(required = false, defaultValue = "") String healthDoctor,
            @RequestParam(required = false, defaultValue = "") String healthDoctorName,
            @RequestParam(required = false, defaultValue = "") String doctor,
            @RequestParam(required = false, defaultValue = "") String doctorName,
            String healthLabel,
            @RequestParam(required = false, defaultValue = "") String customLabel,
            @RequestParam(required = false, defaultValue = "") String disease,
            long msgid,
            String patientIDcard,
            int type,
            long adminTeamCode,
            @RequestParam(required = false, defaultValue = "0") String expenses,
            @RequestParam(required = false) String sevId) {
        try {
            if (type != 2) {
                try {
                    String checkUrl = SystemConf.getInstance().getJwUrl();
                    String jsonString = HttpUtil.sendPost(checkUrl + "/third/sign/CheckSignFamily?idcard=" + patientIDcard, "");

                    if (!StringUtils.isEmpty(jsonString)) {
                        JSONObject checkJson = new JSONObject(jsonString);

                        if (checkJson.getInt("status") == 200) {
                            JSONObject jsonData = checkJson.getJSONObject("data");

                            if (jsonData.getString("status").equals("1")) {
                                messageService.readHealth(msgid);
                                familyContractService.updateSignStatus(patientIDcard);
                                return error(-1, "该居民已在基卫平台签约，无需重复在移动端申请");
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isEmpty(doctor) && StringUtils.isEmpty(healthDoctor) && type != 2) {
                return error(-1, "全科医生或健管师不能为空！");
            }
            if (adminTeamCode <= 0 && type != 2) {
                return error(-1, "团队不能为空！");
            }
            if (StringUtils.isEmpty(healthLabel) && type != 2) {
                return error(-1, "健康情况标签不能为空！");
            }

            JSONObject res = familyContractService.handleSign(signType, getAccessToken(), doctor, doctorName, healthDoctor, healthDoctorName, msgid, patientIDcard, type, healthLabel, customLabel, disease, expenses, adminTeamCode, sevId);
            if (res.getInt("status") == -1) {
                return error(-1, "未知的处理类型！");
            } else if (res.getInt("status") == 0) {
                return error(-1, "操作失败或签约状态已变更！");
            } else if (res.getInt("status") == -2) {
                return error(-2, res.getString("msg")); //居民已签约三师，故全科医生只可为xxx医生，请重新选择全科医生
            } else if (res.getInt("status") == -3) {
                return error(-3, res.getString("msg")); //对不起，居民已签约三师，故只可与XXX医生签约，该签约申请已失效
            } else if (res.getInt("status") == -4) {
                return error(-4, res.getString("msg")); //居民已签约三师，三师签约的全科医生XXX与该签约申请的健管师XXX不在同一个团队，该签约申请已失效
            } else {
                if (type == 1) {
                    return success("已同意患者签约！");
                } else if (type == 2) {
                    return success("已拒绝患者签约！");
                } else {
                    return error(-1, "未知的处理类型！");
                }
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * @param patientCode 患者code
     * @return
     */
    @RequestMapping(value = "getSanshiSign")
    @ResponseBody
    public String getSanshiSign(
            String patientCode, @RequestParam(required = false) String signDoctor) {
        try {
            Map<String, Object> res = familyContractService.getSanshiSignByPatientCode(patientCode);

            if (String.valueOf(res.get("hasSanshi")).equals("true") && StringUtils.isNotEmpty(signDoctor)) {
                List<AdminTeam> teams = teamService.findDoctorsTeams(signDoctor, String.valueOf(res.get("qkCode")));
                res.put("team", teams != null ? teams : new ArrayList<AdminTeam>());
            }

            return write(200, "获取消息列表成功！", "data", res);
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * 患者解约申请处理接口
     *
     * @param msgid   消息id
     * @param patient 患者标识
     * @param type    处理类型：1同意，2拒绝
     * @param reason  解约原因
     * @return
     */
    @RequestMapping(value = "surrender")
    @ResponseBody
    @ObserverRequired
    public String surrender(
            long msgid,
            String patient,
            int type,
            @RequestParam(required = false) String reason) {
        try {
            int res = familyContractService.handleSurrender(getAccessToken(), msgid, patient, type, reason);
            if (res == -1) {
                return error(-1, "未知的处理类型！");
            } else if (res == 0) {
                return error(-1, "操作失败或签约状态已变更！");
            } else if (res == 1) {
                if (type == 1) {
                    return success("解约已生效！");
                } else {
                    return success("已拒绝患者解约申请！");
                }
            }
            return error(-1, "操作失败！");
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * 查询患者相关的签约消息
     *
     * @return
     */
    @RequestMapping(value = "messages")
    @ResponseBody
    public String messages(long id, int pagesize) {
        try {
            JSONArray array = new JSONArray();
            Page<Message> list = familyContractService.findMessageByDoctor(getUID(), id, pagesize);
            if (list != null) {
                for (Message msg : list) {
                    if (msg == null) {
                        continue;
                    }
                    JSONObject json = new JSONObject();
                    // 消息ID
                    json.put("id", msg.getId());
                    // 消息标题
                    json.put("title", msg.getTitle());
                    // 消息内容
                    json.put("message", msg.getContent());
                    // 签约code
                    json.put("signCode", StringUtils.isEmpty(msg.getData()) ? "" : msg.getData());
                    // 消息类型
                    json.put("type", msg.getType());
                    // 发送人标识
                    json.put("sender", msg.getSender());
                    // 发送人姓名
                    json.put("senderName", msg.getSenderName());
                    // 发送人头像
                    json.put("senderPhoto", msg.getSenderPhoto());
                    // 是否已读：1未读，0已读
                    json.put("read", msg.getRead());
                    // 是否已处理，1为未处理，0为已处理
                    json.put("status", msg.getOver());
                    // 是否已处理，1为签约处理，4解约处理
                    json.put("signStatus", msg.getSignStatus());
                    // 解约理由
                    json.put("reason", msg.getReason());
                    // 解约理由
                    json.put("sex", msg.getSex());
                    // 发送时间
                    json.put("czrq", DateUtil.dateToStrLong(msg.getCzrq()));
                    array.put(json);
                }
            }
            return write(200, "获取消息列表成功！", "list", array);
        } catch (Exception e) {
            error(e);
            return error(-1, "获取消息列表失败！");
        }
    }

    public static void main(String[] args) {
        String idcard = "350628198711215041";
        IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
        System.out.println(ie.toString());
        // 校验身份证号
        IdcardValidator validator = new IdcardValidator();
        if (validator.isValidatedAllIdcard(idcard)) {
            if (idcard.length() == 15) {
                idcard = validator.convertIdcarBy15bit(idcard);
            }
        } else {
            System.out.println("请输入正确的身份证号！");
        }
        if (StringUtils.isEmpty(idcard)) {
            System.out.println("请输入正确的身份证号！");
        }
    }

    /**
     * 判断身份证是否存在
     *
     * @return
     */
    @RequestMapping(value = "checkMoblie")
    @ResponseBody
    public String checkMoblie(String mobile) {
        try {
            JSONObject json = new JSONObject();
            SignFamily signFamily = familyContractService.getFamilyContractByMobile(mobile);
            if (signFamily == null) {
                json.put("islive", "true");
            } else {
                json.put("islive", "false");
            }
            return write(200, "验证成功！", "data", json);
        } catch (Exception e) {
            error(e);
            return error(-1, "获取消息列表失败！");
        }
    }

    /**
     * 获取病人的三师签约信息
     *
     * @param idCard
     * @return
     */
    @RequestMapping(value = "patient_sanshi_signinfo")
    @ResponseBody
    public String getPatientSanshiSignByIdCard(String idCard, @RequestParam(required = false) String signDoctor) {
        try {
            if (StringUtils.isEmpty(idCard)) {
                return error(-1, "请输入身份证号!");
            }

            JSONObject result = new JSONObject();

            try {
                String checkUrl = SystemConf.getInstance().getJwUrl();
                String jsonString = HttpUtil.sendPost(checkUrl + "/third/sign/CheckSignFamily?idcard=" + idCard, "");

                if (!StringUtils.isEmpty(jsonString)) {
                    JSONObject checkJson = new JSONObject(jsonString);
                    if (checkJson.getInt("status") == 200) {
                        JSONObject jsonData = checkJson.getJSONObject("data");

                        if (jsonData.getString("status").equals("1")) {
                            result.put("signStatus", "2");
                            result.put("msg", "该居民已在基卫平台签约，无需重复在移动端申请!");
                            return write(200, "查询成功！", "data", result);
                        }
                    }
                }
//                String resultStr = HttpUtil.sendPost(checkUrl + "/third/sign/LoadSanshiSignFamily?idcard=" + idCard, "");
//
//                if (!StringUtils.isEmpty(resultStr)) {
//                    JSONObject checkJson = new JSONObject(resultStr);
//                    if (checkJson.getInt("status") != 200) {
//                        throw new Exception("sanshi sign get from jw failed");
//                    }
//                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            result = familyContractService.getSanshiSingInfoByPatientIdCard(idCard);

            if (result.getString("signStatus").equals("1") && StringUtils.isNotEmpty(signDoctor)) {
                List<AdminTeam> teams = teamService.findDoctorsTeams(signDoctor, result.getString("doctor"));
                result.put("team", teams != null ? new JSONArray(teams) : new JSONArray());
            }

            return write(200, "查询成功!", "data", result);
        } catch (Exception e) {
            return error(-1, "查询失败!");
        }
    }

    /**
     * 更新患者签约补贴类型
     *
     * @param expensesType 补贴类型
     * @param patient      患者
     * @return
     */
    @RequestMapping(value = "/expenses_type_update")
    @ResponseBody
    @ObserverRequired
    public String updateExpensesType(String expensesType, String patient) {
        try {
            if (StringUtils.isEmpty(expensesType)) {
                return error(-1, "补贴类型不能为空");
            }
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "患者不能为空");
            }

            SignFamily familySign = familyContractService.findByPatient(patient);

            if (familySign == null) {
                return error(-1, "居民家庭签约不存在");
            } else {
                if (StringUtils.isNotEmpty(familySign.getMedicalInsuranceNum())) {
                    return error(-1, "数据已上传社保，不能修改补贴类型");
                }
            }

            if (familyContractService.updateExpensesType(expensesType, patient)) {
                return write(200, "更新成功");
            } else {
                return write(-1, "不存在该患者签约");
            }
        } catch (Exception e) {
            return error(-1, "更新失败");
        }
    }

    /**
     * 查询待签约患者数据
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/patient_signing")
    @ResponseBody
    public String getSigningPatientInfo(@RequestParam String patient) {
        try {
            Patient temp = patientInfoService.findByCode(patient);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置患者姓名
                json.put("name", temp.getName());
                // 设置患者头像
                json.put("photo", temp.getPhoto());
                // 设置患者年龄
                json.put("age", DateUtil.getAgeByBirthday(temp.getBirthday()));
                // 设置患者性别
                json.put("sex", temp.getSex());
                // 设置患者病情：0绿标，1黄标，2红标
                json.put("diseaseLevel", temp.getDiseaseCondition());
                // 设置患者身份证号
                json.put("idCard", temp.getIdcard());
                // 设置患者出生年月
                json.put("birthday", DateUtil.dateToStr(temp.getBirthday(), DateUtil.YYYY_MM_DD));
                // 设置患者手机号码
                json.put("mobile", temp.getMobile());
                // 设置患者联系电话
                json.put("phone", temp.getPhone());
                // 设置患者居住省份
                json.put("provinceName", temp.getProvinceName());
                json.put("cityName", temp.getCityName());
                json.put("townName", temp.getTownName());
                json.put("streetName", temp.getStreetName());
                // 设置患者地址
                json.put("address", temp.getAddress());
                //设置患者医保号
                json.put("ssc", temp.getSsc());

                String diseases = redisTemplate.opsForValue().get("disease:" + patient);
                if (!StringUtils.isEmpty(diseases)) {
                    json.put("diseases", new JSONArray(diseases));
                } else {
                    json.put("diseases", "");
                }

                SignFamily jtSign = familyContractService.findSigningByPatient(patient);

                // 家庭签约
                if (jtSign != null) {
                    json.put("applySurrDate", jtSign.getPatientApplyUnsignDate());
                    json.put("applyDate", jtSign.getPatientApplyDate());
                    json.put("jtSign", new JSONObject(jtSign));
                }

                return write(200, "患者信息查询成功！", "data", json);
            } else {
                return error(-1, "患者信息查询失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "患者信息查询失败");
        }
    }

    /**
     * 查询最近签约过期患者数据
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/patient_signing_outtime")
    @ResponseBody
    public String getSigningPatientInfoOutTime(@RequestParam String patient) {
        try {
            Patient temp = patientInfoService.findByCode(patient);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置患者姓名
                json.put("name", temp.getName());
                // 设置患者头像
                json.put("photo", temp.getPhoto());
                // 设置患者年龄
                json.put("age", DateUtil.getAgeByBirthday(temp.getBirthday()));
                // 设置患者性别
                json.put("sex", temp.getSex());
                // 设置患者病情：0绿标，1黄标，2红标
                json.put("diseaseLevel", temp.getDiseaseCondition());
                // 设置患者身份证号
                json.put("idCard", temp.getIdcard());
                // 设置患者出生年月
                json.put("birthday", DateUtil.dateToStr(temp.getBirthday(), DateUtil.YYYY_MM_DD));
                // 设置患者手机号码
                json.put("mobile", temp.getMobile());
                // 设置患者联系电话
                json.put("phone", temp.getPhone());
                // 设置患者居住省份
                json.put("provinceName", temp.getProvinceName());
                json.put("cityName", temp.getCityName());
                json.put("townName", temp.getTownName());
                json.put("streetName", temp.getStreetName());
                // 设置患者地址
                json.put("address", temp.getAddress());
                //设置患者医保号
                json.put("ssc", temp.getSsc());

                String diseases = redisTemplate.opsForValue().get("disease:" + patient);
                if (!StringUtils.isEmpty(diseases)) {
                    json.put("diseases", new JSONArray(diseases));
                } else {
                    json.put("diseases", "");
                }
                //查找患者最近的一次到期记录
                SignFamily jtSign = familyContractService.findOutTimeSigningByPatient(patient);

                // 家庭签约
                if (jtSign != null) {
                    json.put("applySurrDate", jtSign.getPatientApplyUnsignDate());
                    json.put("applyDate", jtSign.getPatientApplyDate());
                    json.put("jtSign", new JSONObject(jtSign));
                }

                return write(200, "患者信息查询成功！", "data", json);
            } else {
                return error(-1, "患者信息查询失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "患者信息查询失败");
        }
    }

    /**
     * 查询待签约患者数据
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/patient_signing_renew")
    @ResponseBody
    public String getSigningRenewPatientInfo(@RequestParam String patient) {
        try {
            Patient temp = patientInfoService.findByCode(patient);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置患者姓名
                json.put("name", temp.getName());
                // 设置患者头像
                json.put("photo", temp.getPhoto());
                // 设置患者年龄
                json.put("age", DateUtil.getAgeByBirthday(temp.getBirthday()));
                // 设置患者性别
                json.put("sex", temp.getSex());
                // 设置患者病情：0绿标，1黄标，2红标
                json.put("diseaseLevel", temp.getDiseaseCondition());
                // 设置患者身份证号
                json.put("idCard", temp.getIdcard());
                // 设置患者出生年月
                json.put("birthday", DateUtil.dateToStr(temp.getBirthday(), DateUtil.YYYY_MM_DD));
                // 设置患者手机号码
                json.put("mobile", temp.getMobile());
                // 设置患者联系电话
                json.put("phone", temp.getPhone());
                // 设置患者居住省份
                json.put("provinceName", temp.getProvinceName());
                json.put("cityName", temp.getCityName());
                json.put("townName", temp.getTownName());
                json.put("streetName", temp.getStreetName());
                // 设置患者地址
                json.put("address", temp.getAddress());
                //设置患者医保号
                json.put("ssc", temp.getSsc());

                String diseases = redisTemplate.opsForValue().get("disease:" + patient);
                if (!StringUtils.isEmpty(diseases)) {
                    json.put("diseases", new JSONArray(diseases));
                } else {
                    json.put("diseases", "");
                }

                SignFamily jtSign = familyContractService.findSigningRenewByPatient(patient);

                // 家庭签约
                if (jtSign != null) {
                    json.put("applySurrDate", jtSign.getPatientApplyUnsignDate());
                    json.put("applyDate", jtSign.getPatientApplyDate());
                    json.put("jtSign", new JSONObject(jtSign));
                } else {
                    throw new Exception("未找到患者待家庭签约的数据");
                }

                return write(200, "患者信息查询成功！", "data", json);
            } else {
                return error(-1, "患者信息查询失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "患者信息查询失败");
        }
    }

    /**
     * 获取家庭签约社保流水号
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/medical_insurance_num")
    @ResponseBody
    public String getMedicalInsuranceNum(String patient) {
        try {
            JSONObject json = new JSONObject();
            SignFamily familySign = familyContractService.findByPatient(patient);

            if (familySign != null) {
                if (StringUtils.isNotEmpty(familySign.getMedicalInsuranceNum())) {
                    json.put("status", 1); // 已上传社保
                    json.put("medicalInsuranceNum", familySign.getMedicalInsuranceNum());
                } else {
                    json.put("status", 0);
                    json.put("medicalInsuranceNum", "");
                }
            } else {
                json.put("status", -1); // 没有家庭签约
                json.put("medicalInsuranceNum", "");
            }

            return write(200, "查询成功", "data", json);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 获取签约数据
     *
     * @param code 签约code
     * @return
     */
    @RequestMapping(value = "/family_sign")
    @ResponseBody
    public String getSignFamily(String code) {
        try {
            if (StringUtils.isEmpty(code)) {
                return error(-1, "参数不能为空");
            }
            SignFamily signFamily = familyContractService.findSignFamilyByCode(code);

            if (signFamily == null) {
                return error(-1, "签约数据不存在");
            }

            return write(200, "查询成功", "data", new JSONObject(signFamily));
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 签约信息变更
     *
     * @param patient      患者code
     * @param healthDoctor 健康管理师code
     * @param expensesType 补贴类型
     * @return
     */
    @RequestMapping(value = "/sign_info_update")
    @ResponseBody
    @ObserverRequired
    public String updateSignInfo(@RequestParam(required = false)String patient, @RequestParam(required = false) String healthDoctor,
                                 @RequestParam(required = false) String doctor,
                                 @RequestParam(required = false) String expensesType) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "患者不能为空");
            }

            if (StringUtils.isEmpty(healthDoctor) && StringUtils.isEmpty(expensesType) && StringUtils.isEmpty(doctor)) {
                return error(-1, "参数不能同时为空");
            }

            JSONObject result = familyContractService.updateSignInfo(patient, healthDoctor, doctor, expensesType, getUID());
            //JSONObject result = familyContractService.updateSignInfo(patient, healthDoctor, doctor, expensesType, "xh1D201703150222");

            if (result.getInt("status") != 1) {
                return error(-1, result.getString("msg"));
            }
            return write(200, "更新成功");
        } catch (Exception e) {
            return error(-1, "更新失败");
        }
    }

    /**
     * 获取没有健康管理师的患者数量
     *
     * @param patientName 患者名称
     * @return
     */
    @RequestMapping(value = "/findNoHealthSignFamilyHealthNum")
    @ResponseBody
    public String findNoHealthSignFamilyHealthNum(
            @RequestParam(required = false) String labelType,
            @RequestParam(required = false) String patientName,
            @RequestParam(required = false) Long teamCode) {
        try {
            //修改年度服务类型1.3.4需求
            if ("1".equals(labelType)) {
                JSONObject rs = familyContractService.getServerPatientList(teamCode);
                return write(200, "查询成功！", "data", rs);
            }

            List listNum = new ArrayList();
            Map patients = new HashMap();
            JSONObject list = familyContractService.findNoHealthSignFamilyHealth(getUID(), labelType, patientName, teamCode);
            List<SignFamily> signFamily = familyContractService.findNoHealthSignFamilyNum(teamCode);
            if (!"4".equals(labelType)) {
                List<SignPatientLabel> s = labelDao.findByLabelTypeAndStatusAndTeamCode(labelType, 1, teamCode);
                for (SignPatientLabel label : s) {
                    Map map = new HashMap();
                    String labelName = label.getLabelName();
                    JSONArray jsonArray = list.getJSONArray(label.getLabelName());
                    List codes = new ArrayList();
                    for (Object patient : jsonArray) {
                        Map tempmap = new HashMap();
                        JSONObject jsonObject = new JSONObject(patient.toString());
                        String code = jsonObject.get("code").toString();
                        tempmap.put("code", code);
                        codes.add(tempmap);
                    }
                    int length = jsonArray.length();
                    map.put("label", labelName);
                    map.put("number", length);
                    map.put("codes", codes);
                    listNum.add(map);
                }

                if (list.has("未标注")) {
                    JSONArray jsonArray = list.getJSONArray("未标注");
                    List codes = new ArrayList();
                    for (Object patient : jsonArray) {
                        Map tempmap = new HashMap();
                        JSONObject jsonObject = new JSONObject(patient.toString());
                        String code = jsonObject.get("code").toString();
                        tempmap.put("code", code);
                        codes.add(tempmap);
                    }
                    Map map = new HashMap();
                    map.put("label", "未标注");
                    map.put("number", jsonArray.length());
                    map.put("codes", codes);
                    listNum.add(map);
                }
            } else {
                if (list.has("孕产妇")) {
                    JSONArray jsonArray = list.getJSONArray("孕产妇");
                    Map map = new HashMap();
                    map.put("label", "孕产妇");
                    List temp = new ArrayList();
                    for (Object str : jsonArray) {
                        Map tempmap = new HashMap();
                        Object code = new JSONObject(str.toString()).get("code");
                        tempmap.put("code", code);
                        temp.add(tempmap);
                    }
                    map.put("codes", temp);
                    map.put("number", jsonArray.length());
                    listNum.add(map);
                }
                if (list.has("未标注")) {
                    JSONArray jsonArray1 = list.getJSONArray("未标注");
                    Map map1 = new HashMap();
                    map1.put("label", "未标注");
                    List temp1 = new ArrayList();
                    for (Object str : jsonArray1) {
                        Map tempmap = new HashMap();
                        Object code = new JSONObject(str.toString()).get("code");
                        tempmap.put("code", code);
                        temp1.add(tempmap);
                    }
                    map1.put("codes", temp1);
                    map1.put("number", jsonArray1.length());
                    listNum.add(map1);
                }
                if (list.has("儿童")) {
                    JSONArray jsonArray2 = list.getJSONArray("儿童");
                    Map map2 = new HashMap();
                    map2.put("label", "儿童");
                    List temp2 = new ArrayList();
                    for (Object str : jsonArray2) {
                        Map tempmap = new HashMap();
                        Object code = new JSONObject(str.toString()).get("code");
                        tempmap.put("code", code);
                        temp2.add(tempmap);
                    }
                    map2.put("codes", temp2);
                    map2.put("number", jsonArray2.length());
                    listNum.add(map2);
                }
            }
            patients.put("count", signFamily.size());
            patients.put("patients", listNum);
            return write(200, "查询成功！", "data", patients);
        } catch (Exception e) {
            error(e);
            return invalidUserException(e, -1, "查询失败");
        }
    }

    /**
     * 获取没有健康管理师的患者列表
     *
     * @param patientName 患者名称
     * @return
     */
    @RequestMapping(value = "/findNoHealthSignFamilyHealth")
    @ResponseBody
    public String findNoHealthSignFamilyHealth(
            String labelType,
            @RequestParam(required = false) String patientName,
            Long teamCode) {
        try {
            JSONObject list = familyContractService.findNoHealthSignFamilyHealth(getUID(), labelType, patientName, teamCode);
            return write(200, "签约数据加载成功！", "data", list);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 搜索患者
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/findNoHealthSignFamilyHealthByParams")
    @ResponseBody
    public String findNoHealthSignFamilyHealthByParams(
            String teamCode,
            String params) {
        try {
            JSONObject list = familyContractService.findNoHealthSignFamilyHealthByParams(getUID(), teamCode, params);
            return write(200, "签约数据加载成功！", "data", list);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 搜索患者
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/findByParamsWithDoctor")
    @ResponseBody
    public String findByParamsWithDoctor(
            String teamCode,
            String params, String doctor, int level) {
        try {
            JSONObject list = familyContractService.findByParamsWithDoctor(doctor, teamCode, params, level);
            return write(200, "签约数据加载成功！", "data", list);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 获取没有健康管理师的签约数据数目
     *
     * @param teamCode 团队code
     * @return
     */
    @RequestMapping(value = "/findNoHealthSignFamilyNum")
    @ResponseBody
    public String findNoHealthSignFamilyNum(long teamCode) {
        try {
            List<SignFamily> signFamily = familyContractService.findNoHealthSignFamilyNum(teamCode);
            JSONObject jo = new JSONObject();
            if (signFamily != null && signFamily.size() > 0) {
                jo.put("date", DateUtil.dateToStr(signFamily.get(0).getCzrq(), "yyyy-MM-dd"));
                jo.put("num", signFamily.size());
            } else {
                jo.put("num", 0);
            }
            return write(200, "查询成功", "data", jo);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 缴费消息提醒
     *
     * @param patient 患者code
     * @return
     */
    @RequestMapping(value = "/expenses_remind")
    @ResponseBody
    @ObserverRequired
    public String remindPatientExpenses(@RequestParam(required = false) String patient
            , @RequestParam(required = false) String isAll) {
        try {
            if (StringUtils.isEmpty(patient) && StringUtils.isEmpty(isAll)) {
                return error(-1, "参数不能都为空");
            }
            String status = redisTemplate.opsForValue().get("expenses:remind:doctor:" + getUID());
            status = StringUtils.isEmpty(status) ? "0" : status;
            if (!status.equals("1")) {
                redisTemplate.opsForValue().set("expenses:remind:doctor:" + getUID(), "1");
                redisTemplate.expire("expenses:remind:doctor:" + getUID(), 20, TimeUnit.MINUTES);
            } else {
                return error(-2, "正在提醒中，请勿重复操作");
            }

            if (StringUtils.isNotEmpty(patient)) {
                JSONObject result = patientRemindService.remindPatientExpenses(patient, getUID());
                redisTemplate.opsForValue().set("expenses:remind:doctor:" + getUID(), "0");
                redisTemplate.expire("expenses:remind:doctor:" + getUID(), 10, TimeUnit.MINUTES);
                return write(result.getInt("status"), result.getString("msg"));
            } else if (StringUtils.isNotEmpty(isAll) && isAll.equals("1")) {
                patientRemindService.remindPatientExpensesAll(getUID());
                return write(200, "提醒操作成功");
            } else {
                redisTemplate.opsForValue().set("expenses:remind:doctor:" + getUID(), "0");
                redisTemplate.expire("expenses:remind:doctor:" + getUID(), 10, TimeUnit.MINUTES);
                return write(-1, "参数错误");
            }
        } catch (Exception e) {
            redisTemplate.opsForValue().set("expenses:remind:doctor:" + getUID(), "0");
            redisTemplate.expire("expenses:remind:doctor:" + getUID(), 10, TimeUnit.MINUTES);
            return error(-1, "提醒失败");
        }
    }

    /**
     * 患者今天是否已提醒缴费
     *
     * @param patient 患者code
     * @return
     */
    @RequestMapping(value = "/is_patient_remind_expenses")
    @ResponseBody
    public String isPatientExpensesRemindToday(String patient) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "患者不能为空");
            }
            int result = 0;
            boolean epTime = redisTemplate.opsForSet().isMember("expenses:remind:set", patient);

            if (!epTime) {
                result = 0;
            } else {
                result = 1;
            }
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 查询居民是否与某个医生存在签约关系
     *
     * @param doctor
     * @return
     */
    @RequestMapping(value = "/doctor_patient_sign_exist", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String isPatientAndDoctorExistSign(@RequestParam(required = true) String doctor,
                                              @RequestParam(required = true) String patient) {
        try {
            if (StringUtils.isEmpty(doctor)) {
                return error(-1, "医生不能为空");
            }
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "居民不能为空");
            }
            JSONObject result = familyContractService.isPatientAndDoctorExistSign(patient, doctor);
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }

    /**
     * 查询居民与某个医生是否可签约
     *
     * @param doctor
     * @return
     */
    @RequestMapping(value = "/doctor_patient_can_sign", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String isPatientAndDoctorCanSign(@RequestParam(required = true) String doctor,
                                            @RequestParam(required = true) String patient) {
        try {
            if (StringUtils.isEmpty(doctor)) {
                return error(-1, "医生不能为空");
            }
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "居民不能为空");
            }
            JSONObject result = familyContractService.isPatientAndDoctorCanSign(patient, doctor);
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 查询患者责任医生、团队医生
     *
     * @param patient 患者
     * @return
     */
    @RequestMapping(value = "/patient_doctors", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String getPatientDoctor(@RequestParam String patient) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "居民不能为空");
            }
            JSONObject result = familyContractService.getPatientDoctors(patient, getUID());
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }


    /**
     * 查询患者责任医生、团队医生
     *
     * @return
     */
    @RequestMapping(value = "/consult_doctors", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String getPatientConsultDoctor(@RequestParam String sessionId) {
        try {
            if (StringUtils.isEmpty(sessionId)) {
                return error(-1, "咨询会话ID不能为空");
            }
            JSONObject result = familyContractService.getTeamDoctors(sessionId, getUID());
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            return error(-1, "查询失败");
        }
    }


    /**
     * 查询患者签约医生
     *
     * @param patient 患者
     * @return
     */
    @RequestMapping(value = "/patient_sign_doctors", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String getPatientSignDoctors(String patient) {
        try {
            JSONObject result = familyContractService.getPatientSignDoctors(patient);
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * 查询患者签约医生
     *
     * @param sessionId 会话ID
     * @return
     */
    @RequestMapping(value = "/patient_team_doctors", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String getPatientSignDoctorsByTeam(String sessionId) {
        try {
            JSONObject result = familyContractService.getPatientSignDoctorsByTeam(sessionId);
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    @RequestMapping(value = "/patient_doctor_teams", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    @ApiOperation(value = "查询医生与居民的团队")
    public String getPatientAndDoctorTeams(@RequestParam @ApiParam(value = "居民code") String patient) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "居民不能为空");
            }

            JSONObject result = familyContractService.getPatientAndDoctorTeams(patient, getUID());
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    /**
     * test
     *
     * @return
     */
    @RequestMapping(value = "/patientGroupByServerType", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据ServerType分组查询医生签约的居民")
    public String patientGroupByServerType() {
        try {
            List<Map<String, Object>> result = familyContractService.patientGroupByServerType(getUID());
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }

    @RequestMapping(value = "/wechat_focus_remind", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    @ApiOperation(value = "微信关注提醒")
    @ObserverRequired
    public String wechatFocusRemind(@RequestParam(defaultValue = "") @ApiParam(value = "居民") String patient,
                                    @RequestParam(defaultValue = "") @ApiParam(value = "是否全部(1:全部  0:非全部)") String isAll) {
        try {
            int result = 200;
            String msg = "提醒成功";
            String status = redisTemplate.opsForValue().get("wechat:focus:remind:doctor:" + getUID());
            status = StringUtils.isEmpty(status) ? "0" : status;
            if (!status.equals("1")) {
                redisTemplate.opsForValue().set("wechat:focus:remind:doctor:" + getUID(), "1");
                redisTemplate.expire("wechat:focus:remind:doctor:" + getUID(), 20, TimeUnit.MINUTES);
            } else {
                result = -1;
                msg = "正在提醒中，请勿重复操作";
            }

            if (isAll.equals("1")) {
                patientRemindService.remindPatientWechatFocusAll(getUID());
            } else {
                if (StringUtils.isEmpty(patient)) {
                    result = -1;
                    msg = "请选择需提醒的居民";
                } else {
                    JSONObject json = patientRemindService.remindPatientFocusWechat(patient, getUID());
                    result = json.getInt("status");
                    msg = json.getString("msg");
                    redisTemplate.opsForValue().set("wechat:focus:remind:doctor:" + getUID(), "0");
                    redisTemplate.expire("wechat:focus:remind:doctor:" + getUID(), 10, TimeUnit.MINUTES);
                }
            }
            return write(result, msg);
        } catch (Exception e) {
            redisTemplate.opsForValue().set("wechat:focus:remind:doctor:" + getUID(), "0");
            redisTemplate.expire("wechat:focus:remind:doctor:" + getUID(), 10, TimeUnit.MINUTES);
            return error(-1, "微信关注提醒失败");
        }
    }


    /**
     * 是否已提醒关注
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/is_patient_remind_focus")
    @ResponseBody
    public String isPatientRemindFocusToday(String patient) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "患者不能为空");
            }
            int result = 0;
            boolean epTime = redisTemplate.opsForSet().isMember("wechat:focus:remind:set", patient);

            if (!epTime) {
                result = 0;
            } else {
                result = 1;
            }
            return write(200, "查询成功", "data", result);
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "查询失败");
        }
    }
}
