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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.wlyy.entity.device.PatientDevice;
import com.yihu.wlyy.entity.message.Message;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.PatientHealthStandard;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.health.entity.DevicePatientHealthIndex;
import com.yihu.wlyy.health.repository.DevicePatientHealthIndexDao;
import com.yihu.wlyy.repository.message.MessageDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.PatientDeviceDao;
import com.yihu.wlyy.repository.patient.PatientHealthStandardDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.service.app.scheduling.DoctorWorkTimeService;
import com.yihu.wlyy.task.HealthIndexUploadTask;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
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 org.springside.modules.utils.Clock;

import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.CommonUtil;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.MessageType;
import com.yihu.wlyy.util.SystemConf;

@Component
@Transactional(rollbackFor = Exception.class)
public class PatientHealthIndexService extends BaseService {

    private Clock clock = Clock.DEFAULT;

    @Autowired
    private PatientDao patientDao;
    @Autowired
    private DevicePatientHealthIndexDao patientHealthIndexDao;
    @Autowired
    private PatientHealthStandardDao patientHealthStandardDao;
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SignFamilyDao signFamilyDao;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private PatientDeviceDao patientDeviceDao;
    @Autowired
    private DoctorWorkTimeService doctorWorkTimeService;

    /**
     * 保存患者健康指标  (旧)
     */
    public DevicePatientHealthIndex save(DevicePatientHealthIndex model, int index, double value, String patientCode)throws Exception {
        model.setCzrq(clock.getCurrentDate());
        model.setDel("1");
        PatientHealthStandard standard = null;
        // 当前值/收缩压，正数为高，负数为低
        double value1 = 0;
        // 上次值/舒张压，正数为高，负数为低
        double value2 = 0;
        if (model.getType() == 1) {
            // 血糖记录，查询患者血糖预警值
            standard = patientHealthStandardDao.findByPatientType(model.getUser(), 1);
            if (index % 2 == 0) {
                // 餐后
                value1 = CommonUtil.checkHealthIndex(value, standard != null && standard.getMaxValue2() > 0 ? standard.getMaxValue2() : SystemConf.HEALTH_STANDARD_ST_MAX_AFTER, standard != null && standard.getMinValue2() > 0 ? standard.getMinValue2() : SystemConf.HEALTH_STANDARD_ST_MIN_AFTER);
            } else {
                // 餐前
                value1 = CommonUtil.checkHealthIndex(value, standard != null && standard.getMaxValue1() > 0 ? standard.getMaxValue1() : SystemConf.HEALTH_STANDARD_ST_MAX_BEFORE, standard != null && standard.getMinValue1() > 0 ? standard.getMinValue1() : SystemConf.HEALTH_STANDARD_ST_MIN_BEFORE);
            }
            // 查询上一次的血糖值
            if (value1 != 0) {
                value2 = NumberUtils.toDouble(findPreValue(model.getUser(), model.getType(), index, model.getRecordDate()), 0);
            }
        } else if (model.getType() == 2) {
            // 血压记录，查询患者血压预警值
            standard = patientHealthStandardDao.findByPatientType(model.getUser(), 2);
            // 收缩压
            value1 = CommonUtil.checkHealthIndex(NumberUtils.toDouble(model.getValue1(), 0), standard != null && standard.getMaxValue1() > 0 ? standard.getMaxValue1() : SystemConf.HEALTH_STANDARD_SSY_MAX, standard != null && standard.getMinValue1() > 0 ? standard.getMinValue1() : SystemConf.HEALTH_STANDARD_SSY_MIN);
            // 舒张压
            value2 = CommonUtil.checkHealthIndex(NumberUtils.toDouble(model.getValue2(), 0), standard != null && standard.getMaxValue2() > 0 ? standard.getMaxValue2() : SystemConf.HEALTH_STANDARD_SZY_MAX, standard != null && standard.getMinValue2() > 0 ? standard.getMinValue2() : SystemConf.HEALTH_STANDARD_SZY_MIN);
            if (value1 > 0 || value2 > 0) {
                value1 = NumberUtils.toDouble(model.getValue1(), 0);
                value2 = NumberUtils.toDouble(model.getValue2(), 0);
            } else if (value1 < 0 || value2 < 0) {
                value1 = -NumberUtils.toDouble(model.getValue1(), 0);
                value2 = -NumberUtils.toDouble(model.getValue2(), 0);
            }
        }
        // 保存到数据库
        model = patientHealthIndexDao.save(model);
        if (value1 != 0) {
            // 消息接收者
            List<String> receivers = new ArrayList<String>();
            // 查询患者信息
            Patient p = patientDao.findByCode(model.getUser());
            // 查询病人家庭签约的健康管理师
            SignFamily signFamily = signFamilyDao.findByjiatingPatientYes(p.getCode());
            String healthDoctorFamily = "";
            if (signFamily != null) {
                healthDoctorFamily = signFamily.getDoctorHealth();
                if (StringUtils.isNotEmpty(healthDoctorFamily)) {
                    // 添加到消息接收人列表
                    receivers.add(healthDoctorFamily);
                }
            }
            // 查询病人三师签约中的健康管理师
            SignFamily signFamilySS = signFamilyDao.findBySanshiPatientYes(p.getCode());
            if (signFamilySS != null) {
                String healthDoctorTeam = signFamilySS.getDoctorHealth();
                // 判断是否是否是同一个健康管理师
                if (StringUtils.isNotEmpty(healthDoctorTeam) && !StringUtils.equals(healthDoctorFamily, healthDoctorTeam)) {
                    // 添加到消息接收人列表
                    receivers.add(healthDoctorTeam);
                }
            }
            List<Message> messages = new ArrayList<Message>();
            JSONArray array = new JSONArray();
            for (String receiver : receivers) {
                if (StringUtils.isEmpty(receiver)) {
                    continue;
                }
                Patient patient = patientDao.findByCode(patientCode);
                // 保存异常消息
                Message message = new Message();
                message.setCzrq(new Date());
                message.setRead(1);
                message.setOver("1");
                message.setReceiver(receiver);
                message.setSender(p.getCode());
                message.setCode(getCode());
                message.setSex(patient.getSex());
                message.setSenderName(p.getName());
                message.setSenderPhoto(p.getPhoto());
                message.setTitle("预警值信息");

                String typeName = "";
                switch (model.getType()) {
                    case 1: {
                        typeName = "血糖";
                        break;
                    }
                    case 2: {
                        typeName = "血压";
                        break;
                    }
                    case 3: {
                        typeName = "体重";
                        break;
                    }
                    case 4: {
                        typeName = "腰围";
                        break;
                    }
                }
                message.setContent(patient.getName() + typeName + "超过预警值");
                message.setType(2);
                message.setValue1(value1);
                message.setValue2(value2);
                message.setTzCode(model.getId() + "");//消息关联的体征id
                message.setTzType(model.getType() + "");//体征类别 （1血糖，2血压，3体重，4腰围）
                messages.add(message);

                // 异常通知
                JSONObject json = new JSONObject();
                json.put("receiver", receiver);
                json.put("type", MessageType.MESSAGE_TYPE_DOCTOR_HEALTH_INDEX.D_HI_01.name());
                json.put("title", MessageType.MESSAGE_TYPE_DOCTOR_HEALTH_INDEX.体征指标.name());
                json.put("msg", p.getName() + "的体征指标出现异常，请及时处理！");
                json.put("data", "");
                JSONObject jsonObject = doctorWorkTimeService.isDoctorWorking(receiver);
                if (jsonObject.getString("status").equals("1")) {
                    //如果在工作时间内就推送
                    array.put(json);  }
            }
            // 批量保存消息
            messageDao.save(messages);
            // 推送消息给医生
            PushMsgTask.getInstance().put(array);
        }
        return model;
    }

    /**
     * 判断当前值是否在区间内
     */
    private boolean checkHealthIndex(Double current, Double max, Double min) {
        if (current > max || current < min || current < 0) {
            return false;
        }
        return true;
    }

    /**
     * 推送信息
     */
    private void sendMessage(String content, Patient patient, DevicePatientHealthIndex model) {
        String patientCode = patient.getCode();
        // 消息接收者
        List<String> receivers = new ArrayList<String>();
        // 查询病人家庭签约的健康管理师
        SignFamily signFamily = signFamilyDao.findByjiatingPatientYes(patientCode);
        String healthDoctorFamily = "";
        if (signFamily != null) {
            healthDoctorFamily = signFamily.getDoctorHealth();
            if (StringUtils.isNotEmpty(healthDoctorFamily)) {
                // 添加到消息接收人列表
                receivers.add(healthDoctorFamily);
            } else {
                // 添加到消息接收人列表
                receivers.add(signFamily.getDoctor());
            }
        }

        // 查询病人三师签约中的健康管理师
        SignFamily signFamilySS = signFamilyDao.findBySanshiPatientYes(patientCode);
        if (signFamilySS != null) {
            String healthDoctorTeam = StringUtils.isNotEmpty(signFamilySS.getDoctorHealth()) ? signFamilySS.getDoctorHealth() : signFamilySS.getDoctor();
            // 判断是否是否是同一个健康管理师
            if (StringUtils.isNotEmpty(healthDoctorTeam) && !StringUtils.equals(healthDoctorFamily, healthDoctorTeam)) {
                // 添加到消息接收人列表
                receivers.add(healthDoctorTeam);
            }
        }
        List<Message> messages = new ArrayList<Message>();
        JSONArray array = new JSONArray();
        for (String receiver : receivers) {
            if (StringUtils.isEmpty(receiver)) {
                continue;
            }
            // 保存异常消息
            Message message = new Message();
            message.setCode(getCode());
            message.setCzrq(new Date());
            message.setRead(1);
            message.setOver("1");
            message.setReceiver(receiver);
            message.setSender(patientCode);
            message.setSex(patient.getSex());
            message.setSenderName(patient.getName());
            message.setSenderPhoto(patient.getPhoto());
            message.setTitle("预警值信息");
            message.setContent(content);
            message.setType(2);
            message.setValue1(Double.valueOf(model.getValue1()));
            message.setValue2(Double.valueOf(model.getValue2()));
            message.setTzCode(String.valueOf(model.getId()));//消息关联的体征id
            message.setTzType(String.valueOf(model.getType()));//体征类别 （1血糖，2血压，3体重，4腰围）
            messages.add(message);

            // 异常通知
            JSONObject json = new JSONObject();
            json.put("receiver", receiver);
            json.put("type", MessageType.MESSAGE_TYPE_DOCTOR_HEALTH_INDEX.D_HI_01.name());
            json.put("title", MessageType.MESSAGE_TYPE_DOCTOR_HEALTH_INDEX.体征指标.name());
            json.put("msg", content);
            json.put("data", "");
            array.put(json);
        }
        // 批量保存消息
        messageDao.save(messages);
        // 推送消息给医生
        PushMsgTask.getInstance().put(array);
    }

    /**
     * 获取患者某天血糖值
     *
     * @return
     */
    private DevicePatientHealthIndex getPatientXT(String patient, String dateString) {
        DevicePatientHealthIndex obj = new DevicePatientHealthIndex();
        obj.setUser(patient);
        boolean hadData = false;
        Date date = DateUtil.strToDateShort(dateString);
        /***************** 按时间排序 ***************************/
        List<DevicePatientHealthIndex> list = patientHealthIndexDao.findByDate(patient, dateString);
        if (list != null && list.size() > 0) {
            obj.setType(1);
            obj.setCzrq(date);
            obj.setRecordDate(date);
            obj.setSortDate(date);
            for (DevicePatientHealthIndex item : list) {
                String data = item.getValue1();
                String dataType = item.getValue2();
                if (data != null && dataType != null) {
                    if (dataType.equals("1")) {
                        obj.setValue1(data);
                        hadData = true;
                    } else if (dataType.equals("2")) {
                        obj.setValue2(data);
                        hadData = true;
                    } else if (dataType.equals("3")) {
                        obj.setValue3(data);
                        hadData = true;
                    } else if (dataType.equals("4")) {
                        obj.setValue4(data);
                        hadData = true;
                    } else if (dataType.equals("5")) {
                        obj.setValue5(data);
                        hadData = true;
                    } else if (dataType.equals("6")) {
                        obj.setValue6(data);
                        hadData = true;
                    } else if (dataType.equals("7")) {
                        obj.setValue7(data);
                        hadData = true;
                    }
                }
            }
        }
        if (hadData) {
            return obj;
        } else {
            return null;
        }
    }

    /**
     * 校验指标是否超标,发送消息
     */
    public void verifyHealthIndex(Long id) {
        //指标信息
        DevicePatientHealthIndex data = patientHealthIndexDao.findOne(id);
        String patientCode = data.getUser();
        //患者信息
        Patient patient = patientDao.findByCode(patientCode);

        int type = data.getType();
        String msgContent = "";
        //血糖校验
        if (type == 1) {
            // 血糖记录，查询患者血糖预警值
            PatientHealthStandard standard = patientHealthStandardDao.findByPatientType(patientCode, 1);
            Double maxValueBefore = SystemConf.HEALTH_STANDARD_ST_MAX_BEFORE;
            Double minValueBefore = SystemConf.HEALTH_STANDARD_ST_MIN_BEFORE;
            Double maxValueAfter = SystemConf.HEALTH_STANDARD_ST_MAX_AFTER;
            Double minValueAfter = SystemConf.HEALTH_STANDARD_ST_MIN_AFTER;
            if (standard != null) {
                if (standard.getMaxValue1() > 0) {
                    maxValueBefore = standard.getMaxValue1();
                }
                if (standard.getMinValue1() > 0) {
                    minValueBefore = standard.getMinValue1();
                }
                if (standard.getMaxValue2() > 0) {
                    maxValueAfter = standard.getMaxValue2();
                }
                if (standard.getMinValue2() > 0) {
                    minValueAfter = standard.getMinValue2();
                }
            }
            int index = Integer.valueOf(data.getValue2());
            String value1 = data.getValue1();
            // 餐后
            if (index % 2 == 0) {
                if (!checkHealthIndex(NumberUtils.toDouble(value1), maxValueBefore, minValueBefore)) {
                    msgContent += patient.getName() + "血糖异常（"+value1+"mmol/L），请处理";
                }
            }
            else { //餐前
                if (!checkHealthIndex(NumberUtils.toDouble(value1), maxValueAfter, minValueAfter)) {
                    msgContent += patient.getName() + "血糖异常（"+value1+"mmol/L），请处理";
                }
            }
        }
        //血压校验
        else if (type == 2) {
            String value1 = data.getValue1();
            String value2 = data.getValue2();
            // 血压记录，查询患者血压预警值
            PatientHealthStandard standard = patientHealthStandardDao.findByPatientType(patientCode, 2);
            Double maxValueSSY = SystemConf.HEALTH_STANDARD_SSY_MAX;
            Double minValueSSY = SystemConf.HEALTH_STANDARD_SSY_MIN;
            Double maxValueSZY = SystemConf.HEALTH_STANDARD_SZY_MAX;
            Double minValueSZY = SystemConf.HEALTH_STANDARD_SZY_MIN;
            if (standard != null) {
                if (standard.getMaxValue1() > 0) {
                    maxValueSSY = standard.getMaxValue1();
                }
                if (standard.getMinValue1() > 0) {
                    minValueSSY = standard.getMinValue1();
                }
                if (standard.getMaxValue2() > 0) {
                    maxValueSZY = standard.getMaxValue2();
                }
                if (standard.getMinValue2() > 0) {
                    minValueSZY = standard.getMinValue2();
                }
            }
            // 收缩压/舒张压校验
            if (!checkHealthIndex(NumberUtils.toDouble(value1), maxValueSSY, minValueSSY)||!checkHealthIndex(NumberUtils.toDouble(value2), maxValueSZY, minValueSZY)) {
                msgContent = patient.getName() +"血压异常（舒张压 "+value2+"mmHg、收缩压 "+value1+"mmHg），请处理";
            }
        }

        //超标则发送消息
        if (msgContent != null && msgContent.length() > 0) {
            sendMessage(msgContent, patient, data);
        }
    }

    /**
     * 新增患者指标
     * 【血糖】{"time":"2016-09-09 17:00:00","gi":"血糖值(mmol/L)"}
     * 【血压】{"time":"2016-09-09 17:00:00","sys":"收缩压(mmHg)","dia":"舒张压(mmHg)","pul":"脉搏（次/分）","ano":"有无心率不齐0否 1是","user":"身份标识"}
     * 【体重】{"time":"2016-09-09 17:00:00","weight":"体重值(kg)"}
     * 【腰围】{"time":"2016-09-09 17:00:00","waistline":"腰围值（cm）"}
     *
     * @return
     */
    public DevicePatientHealthIndex addPatientHealthIndex(String data, String type, String patientCode, String deviceSn) throws Exception {
        Map<String, String> map = (Map<String, String>) objectMapper.readValue(data, Map.class);

        DevicePatientHealthIndex obj = new DevicePatientHealthIndex();
        Date currentTime = new Date();
        obj.setCzrq(currentTime);
        obj.setDel("1");
        Date time = currentTime;
        if (map.containsKey("time")) {
            time = DateUtil.strToDateLong(map.get("time"));
        }
        obj.setRecordDate(time);    //记录时间
        obj.setSortDate(time);      //排序时间

        String idcard = "";
        Patient patient = null;
        if (deviceSn != null && deviceSn.length() > 0)   //设备数据
        {
            obj.setDeviceSn(deviceSn);
            String userType = "-1";
            if (map.containsKey("user")) { //存在身份标识 ,多用户
                userType = map.get("user");
            }
            //根据设备获取患者(不同厂家sn码一样的问题未解决！！)
            PatientDevice device = patientDeviceDao.findByDeviceSnAndCategoryCodeAndUserType(deviceSn, type, userType);
            if (device != null) {
                patientCode = device.getUser();
                patient = patientDao.findByCode(patientCode);
                idcard = device.getUserIdcard();
            }
        }
        //自输数据
        else {
            patient = patientDao.findByCode(patientCode);
            if (patient != null) {
                idcard = patient.getIdcard();
            }
        }

        //身份证不为空
        if (patient != null) {
            obj.setUser(patientCode);
            obj.setIdcard(idcard);

            String msgContent = "";
            // 1血糖 2血压 3体重 4腰围
            switch (type) {
                case "1": {
                    obj.setType(1);
                    String value1 = map.get("gi");  //血糖值
                    String value2 = map.get("gi_type");  //血糖值类型
                    obj.setValue1(value1);
                    obj.setValue2(value2);
                    break;
                }
                case "2": {
                    obj.setType(2);
                    String value1 = map.get("sys");  //收缩压
                    String value2 = map.get("dia");  //舒张压
                    obj.setValue1(value1);
                    obj.setValue2(value2);
                    obj.setValue3(map.get("pul"));     //脉搏
                    obj.setValue4(map.get("ano"));     //有无心率不齐
                    break;
                }
                case "3": {
                    obj.setType(3);
                    obj.setValue1(map.get("weight")); //体重
                    break;
                }
                case "4": {
                    obj.setType(4);
                    obj.setValue1(map.get("waistline"));  //腰围
                    break;
                }
                default: {
                    throw new Exception("暂不支持该指标！");
                }
            }

            patientHealthIndexDao.save(obj);

            //保存完后上传基卫
            new Thread(new HealthIndexUploadTask(String.valueOf(obj.getId()))).start();
        } else {
            throw new Exception("不存在该患者！");
        }

        return obj;
    }


    /**
     * 按录入时间和患者标识查询健康记录
     *
     * @param patientCode
     * @param date
     * @return
     */
    public Iterable<DevicePatientHealthIndex> findByPatienDate(String patientCode, int type, Date date) {
        return patientHealthIndexDao.findByPatienDate(patientCode, type, date);
    }

    /**
     * 按时间段查询患者健康指标
     *
     * @param type  健康指标类型（1血糖，2血压，3体重，4腰围）
     * @param begin 开始时间
     * @param end   结束时间
     * @return
     */
    public List<DevicePatientHealthIndex> findChartByPatien(String patient, int type, String begin, String end) {
        List<DevicePatientHealthIndex> re = new ArrayList<>();

        Date startDate = DateUtil.strToDate(begin, DateUtil.YYYY_MM_DD_HH_MM_SS);
        Date endDate = DateUtil.strToDate(end, DateUtil.YYYY_MM_DD_HH_MM_SS);
        if (type == 1)   //血糖特殊处理
        {
            //根据时间过滤排序
            List<String> dateList = patientHealthIndexDao.findDateList(patient, startDate, endDate, null);
            if (dateList != null && dateList.size() > 0) {
                for (int i = dateList.size() - 1; i >= 0; i--) {
                    String dateString = dateList.get(i);
                    DevicePatientHealthIndex obj = getPatientXT(patient, dateString);
                    if (obj != null) {
                        re.add(obj);
                    }
                }
            }
        } else {
            // 排序
            Sort sort = new Sort(Direction.ASC, "recordDate");
            PageRequest pageRequest = new PageRequest(0, 100, sort);
            re = patientHealthIndexDao.findIndexByPatient(patient, type, startDate, endDate, null).getContent();
        }
        return re;
    }

    /**
     * 查询指标记录
     *
     * @param patient
     * @param type
     * @param start
     * @param end
     * @param page
     * @param pageSize
     * @return
     */
    public List<DevicePatientHealthIndex> findIndexByPatient(String patient, int type, String start, String end, int page, int pageSize) {
        List<DevicePatientHealthIndex> re = new ArrayList<>();
        if (page > 0) {
            page = page - 1;
        }

        Date startDate = DateUtil.strToDate(start, DateUtil.YYYY_MM_DD_HH_MM_SS);
        Date endDate = DateUtil.strToDate(end, DateUtil.YYYY_MM_DD_HH_MM_SS);
        if (type == 1)   //血糖特殊处理
        {
            PageRequest pageRequest = new PageRequest(page, pageSize);
            //根据时间过滤排序
            List<String> dateList = patientHealthIndexDao.findDateList(patient, startDate, endDate, pageRequest);
            if (dateList != null && dateList.size() > 0) {
                for (String dateString : dateList) {
                    DevicePatientHealthIndex obj = getPatientXT(patient, dateString);
                    if (obj != null) {
                        re.add(obj);
                    }
                }
            }
        } else {
            // 排序
            Sort sort = new Sort(Direction.DESC, "recordDate");
            PageRequest pageRequest = new PageRequest(page, pageSize, sort);
            Page<DevicePatientHealthIndex> list = patientHealthIndexDao.findIndexByPatient(patient, type, startDate, endDate, pageRequest);
            re = list.getContent();
        }
        return re;
    }

    /**
     * 根据患者标志获取健康指标
     *
     * @param patientCode 患者标志
     * @param pageSize    页数
     * @return 健康指标列表
     */
    public Page<DevicePatientHealthIndex> findByPatien(String patientCode, int type, Date sortDate, Date begin, Date end, int pageSize) {
        if (pageSize <= 0) {
            pageSize = 10;
        }
        // 排序
        Sort sort = new Sort(Direction.DESC, "sortDate");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pageSize, sort);

        // 设置查询条件
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        // 患者标志
        filters.put("user", new SearchFilter("user", Operator.EQ, patientCode));
        if (sortDate != null) {
            filters.put("sortDate", new SearchFilter("sortDate", Operator.LT, sortDate));
        }
        filters.put("recordDate1", new SearchFilter("recordDate", Operator.GTE, begin));
        filters.put("recordDate2", new SearchFilter("recordDate", Operator.LTE, end));
        filters.put("type", new SearchFilter("type", Operator.EQ, type));
        // 未作废
        filters.put("del", new SearchFilter("del", Operator.EQ, "1"));
        Specification<DevicePatientHealthIndex> spec = DynamicSpecifications.bySearchFilter(filters.values(), DevicePatientHealthIndex.class);

        return patientHealthIndexDao.findAll(spec, pageRequest);
    }

    /**
     * 查询患者健康指标预警值
     *
     * @param patient
     * @return
     */
    public Iterable<PatientHealthStandard> findStandardByPatient(String patient) {
        return patientHealthStandardDao.findByPatient(patient);
    }

    /**
     * 保存患者健康指标预警值
     *
     * @param list
     */
    public Iterable<PatientHealthStandard> saveStandard(List<PatientHealthStandard> list, String patient) {
        // 先删除
        patientHealthStandardDao.deleteByPatient(patient);
        return patientHealthStandardDao.save(list);
    }

    /**
     * 查询患者最近填写的运动、用药、饮食内容
     *
     * @param patient
     * @return
     */
    public JSONArray findRecentByPatient(String patient) {
        JSONArray array = new JSONArray();
        Iterable<DevicePatientHealthIndex> iterable = patientHealthIndexDao.findRecentByPatient(patient);
        if (iterable != null) {
            Iterator<DevicePatientHealthIndex> iterator = iterable.iterator();
            while (iterator != null && iterator.hasNext()) {
                DevicePatientHealthIndex phi = iterator.next();
                if (phi == null) {
                    continue;
                }
                JSONObject json = new JSONObject();
                // 设置健康指标类型（1血糖，2血压，3体重，4腰围）
                json.put("type", phi.getType());
                // 设置血糖/收缩压/体重/腰围/早餐前空腹
                json.put("value1", phi.getValue1());
                // 设置舒张压/早餐后血糖
                json.put("value2", phi.getValue2());
                // 设置午餐前血糖
                json.put("value3", phi.getValue3());
                // 设置午餐后血糖
                json.put("value4", phi.getValue4());
                // 设置晚餐前血糖
                json.put("value5", phi.getValue5());
                // 设置晚餐后血糖
                json.put("value6", phi.getValue6());
                // 设置睡前血糖
                json.put("value7", phi.getValue7());
                json.put("date", DateUtil.dateToStrShort(phi.getRecordDate()));
                array.put(json);
            }
        }
        return array;
    }

    /**
     * 查询上一次的值
     *
     * @param patient 患者标识
     * @param type    类型：1血糖，2血压
     * @param index   第几个值，1~7
     * @return
     */
    private String findPreValue(String patient, int type, int index, Date recordDate) {
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, 1);
        Page<String> page = null;
        switch (index) {
            case 1:
                page = patientHealthIndexDao.findValue1ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 2:
                page = patientHealthIndexDao.findValue2ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 3:
                page = patientHealthIndexDao.findValue3ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 4:
                page = patientHealthIndexDao.findValue4ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 5:
                page = patientHealthIndexDao.findValue5ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 6:
                page = patientHealthIndexDao.findValue6ByPatient(patient, type, recordDate, pageRequest);
                break;
            case 7:
                page = patientHealthIndexDao.findValue7ByPatient(patient, type, recordDate, pageRequest);
                break;
        }
        if (page != null && page.getNumberOfElements() > 0) {
            return page.getContent().get(0);
        }
        return "0";
    }


    /**
     * 根据患者标志获取健康指标
     *
     * @param patientCode 患者标志
     * @return 健康指标列表
     */
    public DevicePatientHealthIndex findLastByPatien(String patientCode, int type) {
        //最新血糖指标
        if (type == 1) {
            DevicePatientHealthIndex obj = patientHealthIndexDao.findLastData(patientCode, 1);
            if (obj != null) {
                String dateString = DateUtil.dateToStrShort(obj.getRecordDate());
                return getPatientXT(patientCode, dateString);
            } else {
                return null;
            }
        } else {  //其他指标
            return patientHealthIndexDao.findLastData(patientCode, 2);
        }
    }


    /**
     * 获取患者健康指标历史记录
     * 1血糖，2血压，3体重，4腰围
     */
    public List<Map<String,String>> getHealthIndexHistory(String patientCode, int type,int page,int pagesize) throws Exception {
        List<Map<String, String>> re = new ArrayList<>();

        // 排序
        Sort sort = new Sort(Direction.DESC, "recordDate");
        PageRequest pageRequest = new PageRequest(page, pagesize, sort);
        List<DevicePatientHealthIndex> list = patientHealthIndexDao.findIndexByPatient(patientCode, type, pageRequest);

        if (list != null && list.size() > 0) {
            for (DevicePatientHealthIndex item : list) {
                Map<String, String> map = new HashMap<>();
                if (type == 1)    //血糖
                {
                    String gi = item.getValue1();
                    String giType = item.getValue2();
                    map.put("time", DateUtil.dateToStrLong(item.getRecordDate()));
                    map.put("gi", gi); //  血糖值
                    map.put("gi_type", giType); //  血糖值类型
                    String text = gi + " mmol/L";
                    if ("1".equals(giType)) {
                        text += "（早餐前）";
                    } else if ("2".equals(giType)) {
                        text += "（早餐后）";
                    } else if ("3".equals(giType)) {
                        text += "（午餐前）";
                    } else if ("4".equals(giType)) {
                        text += "（午餐后）";
                    } else if ("5".equals(giType)) {
                        text += "（晚饭前）";
                    } else if ("6".equals(giType)) {
                        text += "（晚饭后）";
                    } else if ("7".equals(giType)) {
                        text += "（睡前）";
                    }
                    map.put("text", text); //  展示
                    re.add(map);
                } else if (type == 2) //血压
                {
                    String sys = item.getValue1();   //收缩压
                    String dia = item.getValue2();    //舒张压
                    String pul = item.getValue3();    //脉搏
                    map.put("time", DateUtil.dateToStrLong(item.getRecordDate()));
                    map.put("sys", sys);
                    map.put("dia", dia);
                    map.put("pul", pul);
                    re.add(map);
                } else if (type == 3) //体重
                {
                    String weight = item.getValue1();   //体重
                    map.put("time", DateUtil.dateToStrShort(item.getRecordDate()));
                    map.put("weight", weight);
                    map.put("text", weight + " kg");
                    re.add(map);
                }
            }
        }

        return re;
    }

}
