代码副本-健康报告

HealthRecordController

package com.lanxi.hm.controller;

import com.lanxi.basic.model.Opt;
import com.lanxi.basic.model.Page;
import com.lanxi.basic.model.Rs;
import com.lanxi.core.annotation.CustomerLoginRequired;
import com.lanxi.core.annotation.UserLoginRequired;
import com.lanxi.core.model.CustomerBodyMetrics;
import com.lanxi.core.model.UserAccount;
import com.lanxi.core.model.params.PageParam;
import com.lanxi.core.service.CustomerBodyMetricService;
import com.lanxi.hm.model.HealthRecord;
import com.lanxi.hm.model.HealthRecordEntry;
import com.lanxi.hm.model.vo.CommodityAndServiceItemVo;
import com.lanxi.hm.model.vo.CustomerQuestionnaireVo;
import com.lanxi.hm.model.vo.MetricsAnalysisVo;
import com.lanxi.hm.service.HealthRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 健康报告
 * </p>
 *
 * @author hrx
 * @since 2022-08-02
 */
@Api(tags = "健康报告")
@RestController
@RequestMapping("/health-record-entity")
public class HealthRecordController extends LoginRequiredController{

    @Autowired
    private HealthRecordService healthRecordService;

    @Autowired
    private CustomerBodyMetricService customerBodyMetricService;

    @ApiOperation(value = "B端-查询列表")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @GetMapping("/page")
    public Rs<Page<HealthRecord>> pageExamRecord(
            @ApiParam("类型") @RequestParam(value = "serviceType", required = false) String serviceType,
            @ApiParam("服务团队") @RequestParam(value = "serviceTeam", required = false) String serviceTeam,
            @ApiParam("推送状态") @RequestParam(value = "pushStatus", required = false) Integer pushStatus,
            @ApiParam("服务客户") @RequestParam(value = "consumerName", required = false) String consumerName,
            @ApiParam("报告时间-开始") @RequestParam(value = "buildStart", required = false)String buildStart,
            @ApiParam("报告时间-结束") @RequestParam(value = "buildEnd", required = false)String buildEnd,
            @ApiParam("推送时间-开始") @RequestParam(value = "pushStart", required = false)String pushStart,
            @ApiParam("推送时间-结束") @RequestParam(value = "pushEnd", required = false)String pushEnd,
            PageParam pageParam
    ) {
        UserAccount userAccount = currentUserAccount();
        Opt<Page<HealthRecord>> opt = healthRecordService.pageHealthRecord(userAccount, serviceType, serviceTeam, pushStatus, consumerName, buildStart, buildEnd, pushStart, pushEnd, pageParam.getCurrent(), pageParam.getPageSize());
        return Rs.success(opt);
    }

    @ApiOperation(value = "B端-查看详情")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @GetMapping("/getOne")
    public Rs<HealthRecord> getOne(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.getOne(id));
    }


    @ApiOperation(value = "B端-审核操作")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @GetMapping("/push")
    public Rs<Boolean> push(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id ,
            @ApiParam("医生建议") @RequestParam(value = "suggest")String suggest ,
            @ApiParam("商品id列表") @RequestParam(value = "cids", required = false)List<String> cids ,
            @ApiParam("服务项目id列表") @RequestParam(value = "sids", required = false)List<Integer> sids
    ) {
        UserAccount userAccount = currentUserAccount();
        return Rs.success(healthRecordService.push(userAccount, id, suggest, cids, sids));
    }


    @ApiOperation(value = "B端-批量审核")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @PostMapping("/batchPush")
    public Rs<Boolean> batchPush(
            @ApiParam("健康报告id,英文逗号隔开(例如:1,2,3)") @RequestParam(value = "ids") List<Integer> ids
    ) {
        UserAccount userAccount = currentUserAccount();
        return Rs.success(healthRecordService.batchPush(userAccount, ids));
    }

    @ApiOperation(value = "B端-批量下载-待完善")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @PostMapping("/batchDownload")
    public Rs<Boolean> batchDownload(
            @ApiParam("健康报告id,英文逗号隔开(例如:1,2,3)") @RequestParam(value = "ids") List<Integer> ids,
            @ApiParam("request") @RequestParam(value = "request") HttpServletRequest request,
            @ApiParam("response") @RequestParam(value = "response") HttpServletResponse response
    ) {
        UserAccount userAccount = currentUserAccount();
        return Rs.success(healthRecordService.batchDownload(ids, request, response));
    }

    @ApiOperation(value = "C端-顶部建议或统计")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/suggest")
    public Rs<String> findSuggestById(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {

        return Rs.success(healthRecordService.findSuggestById(id));
    }

    @ApiOperation(value = "C端-体重次数和BMI异常次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/countWeightAndBmi")
    public Rs<Map<String, Integer>> countWeightAndBmi(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {

        return Rs.success(healthRecordService.countWeightAndBmi(id));
    }

    @ApiOperation(value = "C端-血压次数和血压异常次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/countBloodPressure")
    public Rs<Map<String, Integer>> countBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {

        return Rs.success(healthRecordService.countBloodPressure(id));
    }

    @ApiOperation(value = "C端-血糖次数和血糖异常次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/countBloodGlucose")
    public Rs<Map<String, Integer>> countBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {

        return Rs.success(healthRecordService.countBloodGlucose(id));
    }

    @ApiOperation(value = "C端-体重数据和BMI数据")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listWeight")
    public Rs<Map<String, List<CustomerBodyMetrics>>> listWeight(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listWeight(id));
    }

    @ApiOperation(value = "C端-体重平均数和BMI平均数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/aveWeightAndBmi")
    public Rs<Map<String, Double>> aveWeightAndBmi(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.aveWeight(id));
    }

    @ApiOperation(value = "C端-血糖数据")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listBloodGlucose")
    public Rs<Map<String, List<CustomerBodyMetrics>>> listBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listBloodGlucose(id));
    }

    @ApiOperation(value = "C端-血糖平均数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/aveBloodGlucose")
    public Rs<Map<String, Double>> aveBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.aveBloodGlucose(id));
    }

    @ApiOperation(value = "C端-血压数据")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listBloodPressure")
    public Rs<Map<String, List<CustomerBodyMetrics>>> listBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listBloodPressure(id));
    }

    @ApiOperation(value = "C端-血压平均数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/aveBloodPressure")
    public Rs<Map<String, Double>> aveBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.aveBloodPressure(id));
    }

    @ApiOperation(value = "C端-体重建议")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @UserLoginRequired
    @GetMapping("/adviceWeight")
    public Rs<String> adviceWeight(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.adviceWeight(id));
    }

    @ApiOperation(value = "C端-血压建议")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/adviceBloodPressure")
    public Rs<String> adviceBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.adviceBloodPressure(id));
    }

    @ApiOperation(value = "C端-血糖建议")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/adviceBloodGlucose")
    public Rs<String> adviceBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.adviceBloodGlucose(id));
    }


    @ApiOperation(value = "C端-近三个月体重数据和BMI数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listWeightPackage")
    public Rs<Map<String, List<MetricsAnalysisVo>>> listWeightPackage(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listWeightPackage(id));
    }

    @ApiOperation(value = "C端-近三个月血压数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listBloodPressurePackage")
    public Rs<Map<String, List<MetricsAnalysisVo>>> listBloodPressurePackage(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listBloodPressurePackage(id));
    }

    @ApiOperation(value = "C端-近三个月血糖数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listBloodGlucosePackage")
    public Rs<Map<String, List<MetricsAnalysisVo>>> listBloodGlucosePackage(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listBloodGlucosePackage(id));
    }

    @ApiOperation(value = "C端-体重结果分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/resultAnalyseWeight")
    public Rs<Map<String, Integer>> resultAnalyseWeight(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.resultAnalyseWeight(id));
    }

    @ApiOperation(value = "C端-血糖结果分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/resultAnalyseBloodGlucose")
    public Rs<Map<String, Integer>> resultAnalyseBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.resultAnalyseBloodGlucose(id));
    }

    @ApiOperation(value = "C端-血压结果分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/resultAnalyseBloodPressure")
    public Rs<Map<String, Integer>> resultAnalyseBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.resultAnalyseBloodPressure(id));
    }


    @ApiOperation(value = "C端-体重数据来源分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/sourceAnalyseWeight")
    public Rs<Map<String, Integer>> sourceAnalyseWeight(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.sourceAnalyseWeight(id));
    }

    @ApiOperation(value = "C端-血糖数据来源分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/sourceAnalyseBloodGlucose")
    public Rs<Map<String, Integer>> sourceAnalyseBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.sourceAnalyseBloodGlucose(id));
    }
    @ApiOperation(value = "C端-血压数据来源分析-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/sourceAnalyseBloodPressure")
    public Rs<Map<String, Integer>> sourceAnalyseBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.sourceAnalyseBloodPressure(id));
    }

    @ApiOperation(value = "C端-体重检测时间的分析 和 各时间段数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/timeAnalyseWeight")
    public Rs<Map<String, List<MetricsAnalysisVo>>> timeAnalyseWeight(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.timeAnalyseWeight(id));
    }

    @ApiOperation(value = "C端-血糖检测时间的分析 和 各时间段数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/timeAnalyseBloodGlucose")
    public Rs<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodGlucose(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.timeAnalyseBloodGlucose(id));
    }


    @ApiOperation(value = "C端-血压检测时间的分析 和 各时间段数据-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/timeAnalyseBloodPressure")
    public Rs<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodPressure(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.timeAnalyseBloodPressure(id));
    }

    @ApiOperation(value = "C端-查询推荐的商品和服务项目-套餐")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/findCidsAndSids")
    public Rs<Map<String, List<CommodityAndServiceItemVo>>> findCidsAndSids(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.findCidsAndSids(id));
    }



    @ApiOperation(value = "C端-查询服务入口")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/listHealthRecordEntry")
    public Rs<List<HealthRecordEntry>> listHealthRecordEntry(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.listHealthRecordEntry(id));
    }


    @ApiOperation(value = "C端-打卡分类统计")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/healthPunch")
    public Rs<Map<String, Integer>> healthPunch(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.healthPunch(id));
    }


    @ApiOperation(value = "C端-打卡总次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/healthPunchCount")
    public Rs<Integer> healthPunchCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.healthPunchCount(id));
    }


    @ApiOperation(value = "C端-健康评估分析列表")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/questionnaireList")
    public Rs<List<CustomerQuestionnaireVo>> questionnaireList(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.questionnaireList(id));
    }

    @ApiOperation(value = "C端-健康评估总次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/questionnaireCount")
    public Rs<Integer> questionnaireCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.questionnaireCount(id));
    }

    @ApiOperation(value = "C端-服务次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/serviceCount")
    public Rs<Integer> serviceCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.serviceCount(id));
    }
    @ApiOperation(value = "C端-服务项目统计")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/serviceItemCount")
    public Rs<Map<String, Integer>> serviceItemCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.serviceItemCount(id));
    }


    @ApiOperation(value = "C端-服务总金额(开关)")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/serviceCost")
    public Rs<BigDecimal> serviceCost(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.serviceCost(id));
    }


    @ApiOperation(value = "C端-服务花费分析(开关)")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/serviceCostList")
    public Rs<Map<String, BigDecimal>> serviceCostList(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.serviceCostList(id));
    }


    @ApiOperation(value = "C端-商城购物次数")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/shopCount")
    public Rs<Integer> shopCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.shopCount(id));
    }


    @ApiOperation(value = "C端-商城商品统计")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/commodityCount")
    public Rs<Map<String, Integer>> commodityCount(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.commodityCount(id));
    }

    @ApiOperation(value = "C端-商城购物金额(开关)")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/shopCost")
    public Rs<BigDecimal> shopCost(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.shopCost(id));
    }


    @ApiOperation(value = "C端-商品花费分析(开关)")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/shopCostList")
    public Rs<Map<String, BigDecimal>> shopCostList(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.shopCostList(id));
    }

    @ApiOperation(value = "C端-判断需要展示哪些指标数据")
    @ApiImplicitParam(name = "Authorization", paramType = "header", required = true)
    @CustomerLoginRequired
    @GetMapping("/showWhatData")
    public Rs<List<String>> showWhatData(
            @ApiParam("健康报告id") @RequestParam(value = "id")Integer id
    ) {
        return Rs.success(healthRecordService.showWhatData(id));
    }


}

HealthRecordService

package com.lanxi.hm.service;

import com.lanxi.basic.model.Op;
import com.lanxi.basic.model.Opt;
import com.lanxi.basic.model.Page;
import com.lanxi.basic.model.Rs;
import com.lanxi.core.model.CustomerBodyMetrics;
import com.lanxi.core.model.UserAccount;
import com.lanxi.hm.model.HealthRecord;
import com.lanxi.hm.model.HealthRecordEntry;
import com.lanxi.hm.model.vo.CommodityAndServiceItemVo;
import com.lanxi.hm.model.vo.CustomerQuestionnaireVo;
import com.lanxi.hm.model.vo.MetricsAnalysisVo;
import org.apache.tomcat.jni.Local;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author hrx
 * @Date 2022/8/2 14:16
 */
public interface HealthRecordService {

    /**
     * 查询健康报告列表
     * @param userAccount 用户
     * @param serviceType 服务类型
     * @param serviceTeam 服务团队
     * @param pushStatus 推送状态
     * @param consumerName 客户姓名
     * @param buildStart 报告开始时间
     * @param buildEnd 报告结束时间
     * @param pushStart 推送开始时间
     * @param pushEnd 推送结束时间
     * @param current 当前页
     * @param pageSize 页尺寸
     * @return
     */
    Opt<Page<HealthRecord>> pageHealthRecord(UserAccount userAccount, String serviceType, String serviceTeam, Integer pushStatus, String consumerName, String buildStart, String buildEnd, String pushStart, String pushEnd, Integer current, Integer pageSize);

    /**
     * 查看详情
     * @param id 健康报告ID
     * @return
     */
    Opt<HealthRecord> getOne(Integer id);

    /**
     * 批量审核
     * @param userAccount 用户
     * @param ids 健康报告ID列表
     * @return
     */
    Opt<Boolean> batchPush(UserAccount userAccount, List<Integer> ids);

    /**
     * 审核
     * @param userAccount 用户
     * @param id 健康报告ID
     * @param suggest 建议
     * @param cids 商品ID列表
     * @param sids 服务ID列表
     * @return
     */
    Opt<Boolean> push(UserAccount userAccount, Integer id, String suggest, List<String> cids, List<Integer> sids);

    /**
     * 测试数据和异常数据统计
     * @param id
     * @param metric
     * @return
     */
    Map<String, Integer> countAndAbCount(Integer id, String metric);

    /**
     * 生成健康报告
     */
    void createHealthRecords();

    /**
     * 查询建议
     * @param id 健康报告ID
     * @return
     */
    Opt<String> findSuggestById(Integer id);

    /**
     * 体检次数 和 BMI异常次数
     *
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Integer>> countWeightAndBmi(Integer id);

    /**
     * 血压次数 和 血压异常次数
     *
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Integer>> countBloodPressure(Integer id);

    /**
     * 血糖次数 和 血糖异常次数
     *
     * @param id 健康报告ID
     * @return key测试数据/异常数据,value值
     */
    Opt<Map<String, Integer>> countBloodGlucose(Integer id);

    /**
     * 根据指标查询数据
     * @param id 健康报告ID
     * @param metric 指标名
     * @return key指标,value指标数据列表
     */
    Opt<Map<String, List<CustomerBodyMetrics>>> findListByIdAndMetric(Integer id, String metric);

    /**
     * 体重变化 和 BMI变化
     *
     * @param id 健康报告ID
     * @return key指标名,value检测列表
     */
    Opt<Map<String, List<CustomerBodyMetrics>>> listWeight(Integer id);

    /**
     * 血糖变化
     *
     * @param id 健康报告ID
     * @return key指标名,value检测列表
     */
    Opt<Map<String, List<CustomerBodyMetrics>>> listBloodGlucose(Integer id);

    /**
     * 血压变化
     *
     * @param id 健康报告ID
     * @return key指标名,value检测列表
     */
    Opt<Map<String, List<CustomerBodyMetrics>>> listBloodPressure(Integer id);

    /**
     * 计算平均数
     * @param id 健康报告ID
     * @param metric key指标名称,value平均数
     * @return
     */
    Opt<Map<String, Double>> getAveByIdAndMetric(Integer id, String metric);


    /**
     * 体重平均数 和 BMI平均数
     *
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Double>> aveWeight(Integer id);

    /**
     * 血糖平均数
     *
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Double>> aveBloodGlucose(Integer id);
    /**
     * 血压平均数
     *
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Double>> aveBloodPressure(Integer id);





    /**
     * 获取体重建议
     * @param id 健康报告ID
     * @return
     */
    Opt<String> adviceWeight(Integer id);

    /**
     * 获取血压建议
     * @param id 健康报告ID
     * @return
     */
    Opt<String> adviceBloodPressure(Integer id);

    /**
     * 获取血糖建议
     * @param id 健康报告ID
     * @return
     */
    Opt<String> adviceBloodGlucose(Integer id);

    /**
     * 按套餐推送-近三个月的数据-体重
     * @param id 健康报告ID
     * @return key指标名,value按月分类的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> listWeightPackage(Integer id);

    /**
     * 按套餐推送-近三个月的数据-血压
     * @param id 健康报告ID
     * @return key指标名,value按月分类的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> listBloodPressurePackage(Integer id);

    /**
     * 按套餐推送-近三个月的数据-血糖
     * @param id 健康报告ID
     * @return key指标名,value按月分类的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> listBloodGlucosePackage(Integer id);

    /**
     * 结果分析
     * @param id 健康报告ID
     * @param metric 指标名
     * @return key指标标签名,value次数
     */
    Opt<Map<String, Integer>> resultAnalyse(Integer id, String metric);


    /**
     * 按套餐推送-结果分析-体重
     * @param id 健康报告ID
     * @return key指标标签,value次数 例如:偏瘦20/正常20/偏旁21/超重22/肥胖25
     */
    Opt<Map<String, Integer>> resultAnalyseWeight(Integer id);

    /**
     * 按套餐推送-结果分析-血糖
     * @param id 健康报告ID
     * @return key指标标签,value次数 例如:偏瘦20/正常20/偏旁21/超重22/肥胖25
     */
    Opt<Map<String, Integer>> resultAnalyseBloodGlucose(Integer id);

    /**
     * 按套餐推送-结果分析-血压
     * @param id 健康报告ID
     * @return key指标标签,value次数 例如:偏瘦20/正常20/偏旁21/超重22/肥胖25
     */
    Opt<Map<String, Integer>> resultAnalyseBloodPressure(Integer id);



    /**
     * 体重数据来源分析
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Integer>> sourceAnalyseWeight(Integer id);

    /**
     * 血糖数据来源分析
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Integer>> sourceAnalyseBloodGlucose(Integer id);

    /**
     * 血压数据来源分析
     * @param id 健康报告ID
     * @return
     */
    Opt<Map<String, Integer>> sourceAnalyseBloodPressure(Integer id);



    /**
     * 体重-检测时间的分析 和 各时间段数据
     * @param id 健康报告ID
     * @return key时间段,value各指标的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseWeight(Integer id);

    /**
     * 血糖-检测时间的分析 和 各时间段数据
     * @param id 健康报告ID
     * @return key时间段,value各指标的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodGlucose(Integer id);

    /**
     * 血压-检测时间的分析 和 各时间段数据
     * @param id 健康报告ID
     * @return key时间段,value各指标的数据列表
     */
    Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodPressure(Integer id);


    /**
     * 查询健康报告服务入口列表
     * @param id 健康报告ID
     * @return
     */
    Opt<List<HealthRecordEntry>> listHealthRecordEntry(Integer id);


    /**
     * 查询推荐的商品和服务项目
     * @param id 健康报告ID
     * @return key类别(商品/服务项目),value商品/服务项目列表
     */
    Opt<Map<String, List<CommodityAndServiceItemVo>>> findCidsAndSids(Integer id);

    /**
     * 打卡分类统计
     * @param id 健康报告ID
     * @return key类别(饮食/运动/睡眠/其他),value次数
     */
    Opt<Map<String, Integer>> healthPunch(Integer id);

    /**
     * 打卡总次数
     * @param id 健康报告ID
     * @return 打卡总次数
     */
    Opt<Integer> healthPunchCount(Integer id);

    /**
     * 健康评估分析列表
     * @param id 健康报告ID
     * @return 健康评估分析列表(健康评估名称、评估结果)
     */
    Opt<List<CustomerQuestionnaireVo>> questionnaireList(Integer id);

    /**
     * 健康评估总次数
     * @param id 健康报告ID
     * @return
     */
    Opt<Integer> questionnaireCount(Integer id);

    /**
     * 服务次数
     * @param id 健康报告ID
     * @return
     */
    Opt<Integer> serviceCount(Integer id);

    /**
     * 服务项目统计
     * @param id 健康报告ID
     * @return key服务项目名称,value次数
     */
    Opt<Map<String, Integer>> serviceItemCount(Integer id);

    /**
     * 服务总金额(开关)
     * @param id 健康报告ID
     * @return 服务总金额
     */
    Opt<BigDecimal> serviceCost(Integer id);

    /**
     * 服务花费分析(开关)
     * @param id 健康报告ID
     * @return key服务项目,value花费
     */
    Opt<Map<String, BigDecimal>> serviceCostList(Integer id);

    /**
     * 商城购物次数
     * @param id 健康报告ID
     * @return
     */
    Opt<Integer> shopCount(Integer id);

    /**
     * 商城商品统计
     * @param id 健康报告ID
     * @return key商品名,value数量
     */
    Opt<Map<String, Integer>> commodityCount(Integer id);

    /**
     * 商城购物金额(开关)
     * @param id 健康报告ID
     * @return
     */
    Opt<BigDecimal> shopCost(Integer id);

    /**
     * 商品花费分析(开关)
     * @param id 健康报告ID
     * @return key商品名,value花费
     */
    Opt<Map<String, BigDecimal>> shopCostList(Integer id);

    /**
     * C端-判断需要调用哪些接口
     * @param id  健康报告ID
     * @return 需要调用的接口集合
     */
    Opt<List<String>> showWhatData(Integer id);

    Opt<Boolean> batchDownload(List<Integer> ids, HttpServletRequest request, HttpServletResponse response);
}

HealthRecordServiceImpl

package com.lanxi.hm.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lanxi.basic.model.Opt;
import com.lanxi.basic.model.Page;
import com.lanxi.core.model.UserAccount;
import com.lanxi.hm.constant.HmConst;
import com.lanxi.core.model.CustomerBodyMetrics;
import com.lanxi.core.model.enums.MessageBizEnum;
import com.lanxi.core.service.CustomerBodyMetricService;
import com.lanxi.hm.dao.hm.*;
import com.lanxi.hm.model.*;
import com.lanxi.hm.model.entity.hm.*;
import com.lanxi.hm.model.vo.CommodityAndServiceItemVo;
import com.lanxi.hm.model.vo.CustomerQuestionnaireVo;
import com.lanxi.hm.model.vo.MetricsAnalysisVo;
import com.lanxi.hm.service.CustomerService;
import com.lanxi.hm.service.HealthRecordService;
import com.lanxi.hm.util.DateTimeUtil;
import com.lanxi.hm.util.DateUtil;
import com.lanxi.hm.util.HealthRecordPushUtil;
import org.apache.tomcat.jni.FileInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author hrx
 * @Date 2022/8/2 14:17
 */
@Service
public class HealthRecordServiceImpl implements HealthRecordService {
    @Autowired
    private final HealthRecordDao healthRecordDao;
    @Autowired
    private HealthRecordPushUtil healthRecordPushUtil;
    @Autowired
    private CustomerPackageDetailDao customerPackageDetailDao;
    @Autowired
    private CustomerPackageDao customerPackageDao;
    @Autowired
    private CustomerDao customerDao;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private CustomerBodyMetricService customerBodyMetricService;
    @Autowired
    private ServiceItemDao serviceItemDao;

    @Autowired
    private MallShopCommodityDao mallShopCommodityDao;

    @Autowired
    private HealthPunchItemDao healthPunchItemDao;


    @Autowired
    private CustomerQuestionnaireDao customerQuestionnaireDao;

    @Autowired
    private QuestionnaireDao questionnaireDao;

    @Autowired
    private ServiceTaskDao serviceTaskDao;

    @Autowired
    private MallShopApptOrderDao mallShopApptOrderDao;

    @Autowired
    private MallShopOrderDao mallShopOrderDao;

    @Autowired
    private MallShopOrderCommodityDao mallShopOrderCommodityDao;


    private String documentPath = "E:\\work\\files";





    public HealthRecordServiceImpl(HealthRecordDao healthRecordDao) {
        this.healthRecordDao = healthRecordDao;
    }

    @Override
    public Opt<Page<HealthRecord>> pageHealthRecord(UserAccount userAccount, String serviceType, String serviceTeam, Integer pushStatus, String consumerName, String buildStart, String buildEnd, String pushStart, String pushEnd, Integer page, Integer size) {
        if (page == null) {
            page = 1;
        }
        if (size == null) {
            size = 30;
        }
        IPage<HealthRecord> iPage = this.healthRecordDao.pageHealthRecord(userAccount.getOrgId(), serviceType, serviceTeam, pushStatus, consumerName, buildStart, buildEnd, pushStart, pushEnd, page, size);

        // 填充用户名、推送时间-格式化
        for (HealthRecord healthRecord : iPage.getRecords()) {
            Opt<CustomerInfoDetail> customerInfoDetail = customerService.getCustomerById(userAccount.getTenantId(), healthRecord.getCustomerId());
            String name = customerInfoDetail.getSome().getName();
            // 用户名
            healthRecord.setCustomerName(name);
            // 推送时间
            if (healthRecord.getPushTime() != null) {
                healthRecord.setPushTimeString(DateUtil.STANDARD_YMD_HM_FORMATTER_2.format(healthRecord.getPushTime()));
            }

        }
        List<HealthRecord> healthRecords = new ArrayList<>();
        for (HealthRecord hr: iPage.getRecords()){
            // 根据租户id查询
            if (userAccount.getTenantId().equals(hr.getTenantId())){
                healthRecords.add(hr);
            }
        }
        return Opt.some(new Page<>(healthRecords, (int) iPage.getTotal(), (int) iPage.getCurrent(), (int) iPage.getSize(), (int) iPage.getPages()));
    }

    @Override
    public Opt<HealthRecord> getOne(Integer id) {
        HealthRecord healthRecord = healthRecordDao.getOneHealthRecord(id);
        Opt<CustomerInfoDetail> customerInfoDetail = customerService.getCustomerById(healthRecord.getTenantId(), healthRecord.getCustomerId());
        String name = customerInfoDetail.getSome().getName();
        // 用户名
        healthRecord.setCustomerName(name);
        // 推送时间
        if (healthRecord.getPushTime() != null) {
            healthRecord.setPushTimeString(DateUtil.STANDARD_YMD_HM_FORMATTER_2.format(healthRecord.getPushTime()));
        }
        return Opt.some(healthRecord);
    }

    @Override
    public Opt<Boolean> batchPush(UserAccount userAccount, List<Integer> ids) {
        boolean flag = false;
        for (Integer id : ids){
            HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
            healthRecordEntity.setPushStatus(1);
            healthRecordEntity.setPushTime(LocalDateTime.now());
            healthRecordEntity.setUserId(userAccount.getId());
            flag = healthRecordDao.updateById(healthRecordEntity);
            // 推送
            String type = HmConst.PUSH_PACKAGE;
            healthRecordPushUtil.sendToMsgCenter(healthRecordEntity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, healthRecordEntity.getId(), healthRecordEntity.getCustomerId(), type);
            healthRecordPushUtil.sendWxMp(healthRecordEntity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, healthRecordEntity.getCustomerId(), healthRecordEntity.getItemId(), healthRecordEntity.getId(), type);
        }
        return Opt.some(flag);
    }

    @Override
    public Opt<Boolean> push(UserAccount userAccount, Integer id, String suggest, List<String> cids, List<Integer> sids) {
        HealthRecordEntity entity = healthRecordDao.getById(id);
        entity.setPushStatus(1);
        LocalDateTime pushTime =  LocalDateTime.of(LocalDate.now(), LocalTime.of(LocalDateTime.now().getHour(), LocalDateTime.now().getMinute()));
        entity.setPushTime(pushTime);
        entity.setUpdateTime(LocalDateTime.now());
        entity.setSuggest(suggest);
        entity.setCommodityIds(String.valueOf(cids));
        entity.setServiceItemIds(String.valueOf(sids));
        entity.setUserId(userAccount.getId());
        boolean flag = healthRecordDao.updateById(entity);
        // 推送
        String type = HmConst.PUSH_PACKAGE;
        healthRecordPushUtil.sendToMsgCenter(entity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, entity.getId(), entity.getCustomerId(), type);
        healthRecordPushUtil.sendWxMp(entity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, entity.getCustomerId(), entity.getItemId(), entity.getId(), type);
        return Opt.some(flag);

    }

    @Override
    public void createHealthRecords() {
        // 查询所有客户
        List<CustomerEntity> customersAll = customerDao.list();
        List<CustomerPackageEntity> customerPackageEntities = customerPackageDao.list().stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getCustomerId()))), ArrayList::new));

        List<CustomerEntity> customers = new ArrayList<>();
        for (CustomerPackageEntity cus : customerPackageEntities){
            // 绑定了套餐的客户 - 按服务套餐生成
            customers.add(customerDao.getById(cus.getCustomerId()));
        }
        // 未绑定套餐的客户
        customersAll.removeAll(customers);

        List<CustomerEntity> customersB = new ArrayList<>();
        List<CustomerBodyMetrics> customerBodyMatterList = customerBodyMetricService.listCount15().some();
        for (CustomerBodyMetrics cbm : customerBodyMatterList){
            CustomerEntity customer = customerDao.getById(cbm.getCustomerId());
            customersB.add(customer);
        }
        // 未绑定套餐的客户 且 次数大于15的客户 - 默认生成
        customersB.retainAll(customersAll);



        // 1. 默认生成
        // 健康报告列表
        for(CustomerEntity ce : customersB){
            HealthRecordEntity healthRecordEntity = new HealthRecordEntity();
            healthRecordEntity.setCustomerId(ce.getId());
            healthRecordEntity.setTeamId(ce.getServiceTeamId());
            healthRecordEntity.setPushCycle(1);

            LocalDate now = LocalDate.now();
            LocalDate lastMonth = now.minusMonths(1);
            LocalDate firstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth());
            LocalDate lastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth());

            String first = DateUtil.STANDARD_ONLINE_SETTING_FORMATTER.format(firstDay);
            String last = DateUtil.STANDARD_ONLINE_SETTING_FORMATTER.format(lastDay);
            healthRecordEntity.setRecordTime(first+"~"+last);

            healthRecordEntity.setHrType(0);
            healthRecordEntity.setPushStatus(0);
            healthRecordEntity.setTenantId(String.valueOf(ce.getTenantId()));
            healthRecordDao.save(healthRecordEntity);
            String type = HmConst.PUSH_DEFAULT;
            healthRecordPushUtil.sendToMsgCenter(healthRecordEntity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, healthRecordEntity.getId(), healthRecordEntity.getCustomerId(), type);
            healthRecordPushUtil.sendWxMp(healthRecordEntity.getTenantId(), MessageBizEnum.HEALTH_RECORD_PUSH, healthRecordEntity.getCustomerId(), healthRecordEntity.getItemId(), healthRecordEntity.getId(), type);

        }

        // 2. 按服务套餐生成
        // 健康报告列表
        for(CustomerEntity c : customers){
            List<CustomerPackageDetailEntity> customerPackageDetailEntityList = new ArrayList<>();
            // 查询此用户绑定的套餐列表
            List<CustomerPackageEntity> list = customerPackageDao.listByCustomerId(c.getId());

            for (CustomerPackageEntity cp : list){
                // 根据客户套餐ID查询服务项目列表
                customerPackageDetailEntityList.addAll(customerPackageDetailDao.findServiceItemByCcustomerPackageId(cp.getId()));
            }
            // 根据 服务项目ID 进行去重
            customerPackageDetailEntityList = customerPackageDetailEntityList.stream().collect(
                    Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CustomerPackageDetailEntity::getServiceItemId))), ArrayList::new));
            for (CustomerPackageDetailEntity cpd : customerPackageDetailEntityList){
                HealthRecordEntity healthRecordEntity = new HealthRecordEntity();
                healthRecordEntity.setCustomerId(c.getId());
                healthRecordEntity.setTeamId(c.getServiceTeamId());
                // 上传周期(0周、1月、2季、3年)
                String params = serviceItemDao.getById(cpd.getServiceItemId()).getParams();
                Map paramsMap = JSON.parseObject(params, Map.class);
                String cycle = (String) paramsMap.get(HmConst.METRIC_TYPE_CYCLE);
                LocalDate firstDay = LocalDate.now();
                LocalDate lastDay = LocalDate.now();
                if (HmConst.METRIC_TYPE_WEEK.equals(cycle)){
                    healthRecordEntity.setPushCycle(0);
                    LocalDate now = LocalDate.now();
                    LocalDate todayOfLastWeek = now.minusDays(7);
                    firstDay = todayOfLastWeek.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1);
                    lastDay = todayOfLastWeek.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).minusDays(1);
                } else if (HmConst.METRIC_TYPE_MONTH.equals(cycle)) {
                    healthRecordEntity.setPushCycle(1);
                    LocalDate now = LocalDate.now();
                    LocalDate lastMonth = now.minusMonths(1);
                    firstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth());
                    lastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth());
                } else if (HmConst.METRIC_TYPE_QUARTER.equals(cycle)) {
                    healthRecordEntity.setPushCycle(2);
                    LocalDate now = LocalDate.now();
                    int monthValue = now.getMonthValue();

                    if (monthValue <= 3){
                        LocalDate lastYear = now.minusYears(1);
                        firstDay = LocalDate.of(lastYear.getYear(), 10,1);
                        lastDay = LocalDate.of(lastYear.getYear(), 12,31);
                    } else if(monthValue <= 6){
                        firstDay = LocalDate.of(now.getYear(), 1,1);
                        lastDay = LocalDate.of(now.getYear(), 3,31);
                    } else if(monthValue <= 9){
                        firstDay = LocalDate.of(now.getYear(), 4,1);
                        lastDay = LocalDate.of(now.getYear(), 6,30);
                    } else {
                        firstDay = LocalDate.of(now.getYear(), 7,1);
                        lastDay = LocalDate.of(now.getYear(), 9,30);
                    }
                } else if (HmConst.METRIC_TYPE_YEAR.equals(cycle)) {
                    healthRecordEntity.setPushCycle(3);
                    LocalDate now = LocalDate.now();
                    LocalDate lastYear = now.minusYears(1);
                    firstDay = lastYear.with(TemporalAdjusters.firstDayOfYear());
                    lastDay = lastYear.with(TemporalAdjusters.lastDayOfYear());
                }
                String first = DateUtil.STANDARD_ONLINE_SETTING_FORMATTER.format(firstDay);
                String last = DateUtil.STANDARD_ONLINE_SETTING_FORMATTER.format(lastDay);
                healthRecordEntity.setRecordTime(first+"~"+last);
                healthRecordEntity.setHrType(0);
                healthRecordEntity.setPushStatus(0);
                healthRecordDao.save(healthRecordEntity);

            }
        }
    }

    @Override
    public Opt<String> findSuggestById(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        LocalDateTime lastTime = healthRecordEntity.getCreateTime().minusMonths(1);

        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);

        String result = lastTime.getYear()+"年"+lastTime.getMonthValue()+"月您一共完成了";
        if (healthRecordEntity.getHrType() == 0) {
            // 默认推荐 返回统计

            // 体重次数
            Opt<Integer> countWeight = customerBodyMetricService.countTest(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_WEIGHT, 0);

            // 血压次数
            Opt<Integer> countBloodPressure = customerBodyMetricService.countTest(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BLOODPRESSURE, 0);

            // 血糖次数
            Opt<Integer> countBloodGlucose = customerBodyMetricService.countTest(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BLOODGLUCOSE, 0);

            if (countWeight.some() > 0) {
                result += countWeight.some()+"次体重检测,";
            }
            if (countWeight.some() > 0) {
                result += countBloodPressure.some()+"次血糖检测,";
            }
            if (countWeight.some() > 0) {
                result += countBloodGlucose.some()+"次血压检测,";
            }
            result += "您的检测习惯非常优秀,8月要继续保持哦~";
            return Opt.some(result);
        } else {
            // 按套餐推荐 返回建议
            return Opt.some(healthRecordEntity.getSuggest());
        }

    }

    @Override
    public Map<String, Integer> countAndAbCount(Integer id, String metric) {
        String customerId = healthRecordDao.getById(id).getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);

        Map<String, Integer> map = new HashMap<>();
        map.put("检测次数", customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some());
        map.put("异常次数", customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some());

        return map;
    }
    @Override
    public Opt<Map<String, Integer>> countWeightAndBmi(Integer id) {
        return Opt.some(this.countAndAbCount(id,HmConst.METRIC_TYPE_WEIGHT));
    }

    @Override
    public Opt<Map<String, Integer>> countBloodPressure(Integer id) {
        return Opt.some(this.countAndAbCount(id,HmConst.METRIC_TYPE_BLOODPRESSURE));
    }

    @Override
    public Opt<Map<String, Integer>> countBloodGlucose(Integer id) {
        return Opt.some(this.countAndAbCount(id,HmConst.METRIC_TYPE_BLOODGLUCOSE));
    }

    @Override
    public Opt<Map<String, List<CustomerBodyMetrics>>> findListByIdAndMetric(Integer id, String metric) {
        Map<String, List<CustomerBodyMetrics>> map = new HashMap<>();
        String customerId = healthRecordDao.getById(id).getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);
        if (HmConst.METRIC_TYPE_WEIGHT.equals(metric)){
            map.put(HmConst.METRIC_TYPE_WEIGHT, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_WEIGHT).some());
            map.put(HmConst.METRIC_TYPE_BMI, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BMI).some());
        } else if (HmConst.METRIC_TYPE_BLOODGLUCOSE.equals(metric)) {
            map.put(HmConst.METRIC_TYPE_FASTING, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_FASTING).some());
            map.put(HmConst.METRIC_TYPE_BEFOREMEAL, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BEFOREMEAL).some());
            map.put(HmConst.METRIC_TYPE_AFTERMEAL, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_AFTERMEAL).some());
            map.put(HmConst.METRIC_TYPE_NIGHT, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_NIGHT).some());
        } else if (HmConst.METRIC_TYPE_BLOODPRESSURE.equals(metric)) {
            map.put(HmConst.METRIC_TYPE_DIASTOLICPRESSURE, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_DIASTOLICPRESSURE).some());
            map.put(HmConst.METRIC_TYPE_HEARTPATEOFBP, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_HEARTPATEOFBP).some());
            map.put(HmConst.METRIC_TYPE_SYSTOLICPRESSURE, customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_SYSTOLICPRESSURE).some());
        }
        return Opt.some(map);
    }
    @Override
    public Opt<Map<String, List<CustomerBodyMetrics>>> listWeight(Integer id) {
        return Opt.some(this.findListByIdAndMetric(id, HmConst.METRIC_TYPE_WEIGHT).some());
    }

    @Override
    public Opt<Map<String, Double>> getAveByIdAndMetric(Integer id, String metric) {
        String customerId = healthRecordDao.getById(id).getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);
        Map<String, Double> map = new HashMap<>();
        if (HmConst.METRIC_TYPE_WEIGHT.equals(metric)){
            map.put(HmConst.METRIC_TYPE_WEIGHT, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_WEIGHT).some());
            map.put(HmConst.METRIC_TYPE_BMI, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BMI).some());
        } else if (HmConst.METRIC_TYPE_BLOODGLUCOSE.equals(metric)) {
            map.put(HmConst.METRIC_TYPE_FASTING, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_FASTING).some());
            map.put(HmConst.METRIC_TYPE_BEFOREMEAL, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_BEFOREMEAL).some());
            map.put(HmConst.METRIC_TYPE_AFTERMEAL, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_AFTERMEAL).some());
            map.put(HmConst.METRIC_TYPE_NIGHT, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_NIGHT).some());
        } else if (HmConst.METRIC_TYPE_BLOODPRESSURE.equals(metric)) {
            map.put(HmConst.METRIC_TYPE_DIASTOLICPRESSURE, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_DIASTOLICPRESSURE).some());
            map.put(HmConst.METRIC_TYPE_HEARTPATEOFBP, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_HEARTPATEOFBP).some());
            map.put(HmConst.METRIC_TYPE_SYSTOLICPRESSURE, customerBodyMetricService.getAve(customerId, firstDay, lastDay, HmConst.METRIC_TYPE_SYSTOLICPRESSURE).some());
        }
        return Opt.some(map);
    }
    @Override
    public Opt<Map<String, Double>> aveWeight(Integer id) {
        return Opt.some(this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_WEIGHT).some());
    }

    @Override
    public Opt<Map<String, List<CustomerBodyMetrics>>> listBloodGlucose(Integer id) {
        return Opt.some(this.findListByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODGLUCOSE).some());
    }

    @Override
    public Opt<Map<String, Double>> aveBloodGlucose(Integer id) {
        return Opt.some(this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODGLUCOSE).some());
    }

    @Override
    public Opt<Map<String, List<CustomerBodyMetrics>>> listBloodPressure(Integer id) {
        return Opt.some(this.findListByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODPRESSURE).some());
    }

    @Override
    public Opt<Map<String, Double>> aveBloodPressure(Integer id) {
        return Opt.some(this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODPRESSURE).some());
    }

    @Override
    public Opt<String> adviceWeight(Integer id) {
        Map<String, Double> aveMap = this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_WEIGHT).some();
        Double aveWeight = aveMap.get(HmConst.METRIC_TYPE_WEIGHT);
        Double aveBmi = aveMap.get(HmConst.METRIC_TYPE_BMI);
        String advice = "您本月体重的平均值为"+aveWeight+"kg,BMI的平均值为"+aveBmi+",";
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_BMI, aveBmi).some();
        return Opt.some(advice);
    }

    @Override
    public Opt<String> adviceBloodPressure(Integer id) {
        Map<String, Double> aveMap = this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODPRESSURE).some();
        Double diastolicPressure = aveMap.get(HmConst.METRIC_TYPE_DIASTOLICPRESSURE);
        Double heartRateOfBP = aveMap.get(HmConst.METRIC_TYPE_HEARTPATEOFBP);
        Double systolicPressure = aveMap.get(HmConst.METRIC_TYPE_SYSTOLICPRESSURE);
        String advice = "您本月舒张压的平均值为"+diastolicPressure+",收缩压的平均值为"+systolicPressure+",心率的平均值为"+heartRateOfBP+",";
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_DIASTOLICPRESSURE, diastolicPressure).some();
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_HEARTPATEOFBP, heartRateOfBP).some();
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_SYSTOLICPRESSURE, systolicPressure).some();
        return Opt.some(advice);
    }

    @Override
    public Opt<String> adviceBloodGlucose(Integer id) {
        Map<String, Double> aveMap = this.getAveByIdAndMetric(id, HmConst.METRIC_TYPE_BLOODGLUCOSE).some();
        Double fasting = aveMap.get(HmConst.METRIC_TYPE_FASTING);
        Double beforeMeal = aveMap.get(HmConst.METRIC_TYPE_BEFOREMEAL);
        Double afterMeal = aveMap.get(HmConst.METRIC_TYPE_AFTERMEAL);
        Double night = aveMap.get(HmConst.METRIC_TYPE_NIGHT);
        String advice = "您本月空腹血糖的平均值为"+fasting+"mmol/l,餐前血糖的平均值为"+beforeMeal+"mmol/l,餐后血糖的平均值为"+afterMeal+"mmol/l,晚上血糖平均值为"+night+"mmol/l,";
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_FASTING, fasting).some();
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_BEFOREMEAL, beforeMeal).some();
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_AFTERMEAL, afterMeal).some();
        advice += customerBodyMetricService.getAdvice(HmConst.METRIC_TYPE_NIGHT, night).some();
        return Opt.some(advice);
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> listWeightPackage(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        Integer pushCycle = healthRecordEntity.getPushCycle();
        String customerId = healthRecordEntity.getCustomerId();

        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        // 报告时间的最后一天
        LocalDateTime last = recordTime.get(HmConst.LAST_DAY);
        LocalDateTime first = recordTime.get(HmConst.FIRST_DAY);

        // 计算上月始末时间
        Map<String, LocalDateTime> lastMonth = new HashMap<>();
        
        Map<String, List<MetricsAnalysisVo>> map = new HashMap<>();
        List<MetricsAnalysisVo> weightList = new ArrayList<>();
        List<MetricsAnalysisVo> bmiList = new ArrayList<>();
        MetricsAnalysisVo weight = null;
        MetricsAnalysisVo bmi = null;
        if (pushCycle == 1 || pushCycle == 2) {
            // 周期为月/季
            for(int i = 0; i< 3; i++) {
                // 计算上月始末时间
                if (i == 0) {
                    lastMonth = this.lastMonthStartAndEnd(last).some();
                } else {
                    lastMonth = this.lastMonthStartAndEnd(last.minusMonths(1)).some();
                }

                first = lastMonth.get(HmConst.FIRST_DAY);
                last = lastMonth.get(HmConst.LAST_DAY);
                weight = this.weghtListByMonth(customerId, first, last, HmConst.METRIC_TYPE_WEIGHT).some();
                bmi = this.bmiListByMonth(customerId, first, last, HmConst.METRIC_TYPE_BMI).some();
                weightList.add(weight);
                bmiList.add(bmi);
            }
            map.put(HmConst.METRIC_TYPE_WEIGHT,weightList);
            map.put(HmConst.METRIC_TYPE_BMI,bmiList);
        }

        return Opt.some(map);
    }

    private Opt<MetricsAnalysisVo> weghtListByMonth(String customerId,LocalDateTime firstDay, LocalDateTime lastDay, String metric) {

        // 检测数量
        Integer countWeight = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abWeight = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxWeight = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minWeight = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> weightData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();

        MetricsAnalysisVo mWeight = new MetricsAnalysisVo();
        mWeight.setMonth(firstDay.getMonthValue());
        mWeight.setCountTest(countWeight);
        mWeight.setCountAb(abWeight);
        mWeight.setMaxValue(maxWeight);
        mWeight.setMinValue(minWeight);
        mWeight.setCustomerBodyMetricsList(weightData);
        mWeight.setMetric(metric);

        return Opt.some(mWeight);
    }
    private Opt<MetricsAnalysisVo> bmiListByMonth(String customerId,LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 上1个月
        // 检测数量
        Integer countAbBmi = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abBmi = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxBmi = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minBmi = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> bmiDate = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();

        MetricsAnalysisVo mBmi = new MetricsAnalysisVo();
        mBmi.setMonth(firstDay.getMonthValue());
        mBmi.setCountTest(countAbBmi);
        mBmi.setCountAb(abBmi);
        mBmi.setMaxValue(maxBmi);
        mBmi.setMinValue(minBmi);
        mBmi.setCustomerBodyMetricsList(bmiDate);
        mBmi.setMetric(metric);

        return Opt.some(mBmi);
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> listBloodGlucosePackage(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        Integer pushCycle = healthRecordEntity.getPushCycle();
        String customerId = healthRecordEntity.getCustomerId();

        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime last = recordTime.get(HmConst.LAST_DAY);
        LocalDateTime first = recordTime.get(HmConst.FIRST_DAY);

        Map<String, LocalDateTime> lastMonth = new HashMap<>();

        Map<String, List<MetricsAnalysisVo>> map = new HashMap<>();
        List<MetricsAnalysisVo> fastingList = new ArrayList<>();
        List<MetricsAnalysisVo> beforeMealList = new ArrayList<>();
        List<MetricsAnalysisVo> afterMealList = new ArrayList<>();
        List<MetricsAnalysisVo> nightList = new ArrayList<>();
        MetricsAnalysisVo fasting = null;
        MetricsAnalysisVo beforeMeal = null;
        MetricsAnalysisVo afterMeal = null;
        MetricsAnalysisVo night = null;
        if (pushCycle == 1 || pushCycle == 2) {
            // 周期为月/季
            for(int i = 0; i< 3; i++) {
                // 计算上月始末时间
                if (i == 0) {
                    lastMonth = this.lastMonthStartAndEnd(last).some();
                } else {
                    lastMonth = this.lastMonthStartAndEnd(last.minusMonths(1)).some();
                }
                first = lastMonth.get(HmConst.FIRST_DAY);
                last = lastMonth.get(HmConst.LAST_DAY);
                fasting = this.fastingListByMonth(customerId, first, last, HmConst.METRIC_TYPE_FASTING).some();
                beforeMeal = this.beforeMealListByMonth(customerId, first, last, HmConst.METRIC_TYPE_BEFOREMEAL).some();
                afterMeal = this.afterMealListByMonth(customerId, first, last, HmConst.METRIC_TYPE_AFTERMEAL).some();
                night = this.nightListByMonth(customerId, first, last, HmConst.METRIC_TYPE_NIGHT).some();
                fastingList.add(fasting);
                beforeMealList.add(beforeMeal);
                afterMealList.add(afterMeal);
                nightList.add(night);
            }
            map.put(HmConst.METRIC_TYPE_FASTING,fastingList);
            map.put(HmConst.METRIC_TYPE_BEFOREMEAL,beforeMealList);
            map.put(HmConst.METRIC_TYPE_AFTERMEAL,afterMealList);
            map.put(HmConst.METRIC_TYPE_NIGHT,nightList);
        }

        return Opt.some(map);
    }

    private Opt<MetricsAnalysisVo> nightListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countNight = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abNight = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxNight = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minNight = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> nightData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();


        MetricsAnalysisVo mNight = new MetricsAnalysisVo();
        mNight.setMonth(firstDay.getMonthValue());
        mNight.setCountTest(countNight);
        mNight.setCountAb(abNight);
        mNight.setMaxValue(maxNight);
        mNight.setMinValue(minNight);
        mNight.setCustomerBodyMetricsList(nightData);
        mNight.setMetric(metric);

        return Opt.some(mNight);
    }

    private Opt<MetricsAnalysisVo> afterMealListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countAfterMeal = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abAfterMeal = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxAfterMeal = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minAfterMeal = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> afterMealData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();

        MetricsAnalysisVo mAfterMeal = new MetricsAnalysisVo();
        mAfterMeal.setMonth(firstDay.getMonthValue());
        mAfterMeal.setCountTest(countAfterMeal);
        mAfterMeal.setCountAb(abAfterMeal);
        mAfterMeal.setMaxValue(maxAfterMeal);
        mAfterMeal.setMinValue(minAfterMeal);
        mAfterMeal.setCustomerBodyMetricsList(afterMealData);
        mAfterMeal.setMetric(metric);
        return Opt.some(mAfterMeal);
    }

    private Opt<MetricsAnalysisVo> beforeMealListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countBeforeMeal = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abBeforeMeal = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxBeforeMeal = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minBeforeMeal = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();
        // 列表
        List<CustomerBodyMetrics> beforeMealData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();


        MetricsAnalysisVo mBeforeMeal = new MetricsAnalysisVo();
        mBeforeMeal.setMonth(firstDay.getMonthValue());
        mBeforeMeal.setCountTest(countBeforeMeal);
        mBeforeMeal.setCountAb(abBeforeMeal);
        mBeforeMeal.setMaxValue(maxBeforeMeal);
        mBeforeMeal.setMinValue(minBeforeMeal);
        mBeforeMeal.setCustomerBodyMetricsList(beforeMealData);
        mBeforeMeal.setMetric(metric);
        return Opt.some(mBeforeMeal);
    }

    private Opt<MetricsAnalysisVo> fastingListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countFasting = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abFasting = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxFasting = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minFasting = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> fastingData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();
        MetricsAnalysisVo mFasting = new MetricsAnalysisVo();
        mFasting.setMonth(firstDay.getMonthValue());
        mFasting.setCountTest(countFasting);
        mFasting.setCountAb(abFasting);
        mFasting.setMaxValue(maxFasting);
        mFasting.setMinValue(minFasting);
        mFasting.setCustomerBodyMetricsList(fastingData);
        mFasting.setMetric(metric);

        return Opt.some(mFasting);
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> listBloodPressurePackage(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        Integer pushCycle = healthRecordEntity.getPushCycle();
        String customerId = healthRecordEntity.getCustomerId();

        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime last = recordTime.get(HmConst.LAST_DAY);
        LocalDateTime first = recordTime.get(HmConst.FIRST_DAY);

        Map<String, LocalDateTime> lastMonth = new HashMap<>();

        Map<String, List<MetricsAnalysisVo>> map = new HashMap<>();
        List<MetricsAnalysisVo> diastolicPressureList = new ArrayList<>();
        List<MetricsAnalysisVo> heartRateOfBPList = new ArrayList<>();
        List<MetricsAnalysisVo> systolicPressureList = new ArrayList<>();
        MetricsAnalysisVo diastolicPressure = null;
        MetricsAnalysisVo heartRateOfBP = null;
        MetricsAnalysisVo systolicPressure = null;
        if (pushCycle == 1 || pushCycle == 2) {
            // 周期为月/季
            for(int i = 0; i< 3; i++) {
                // 计算上月始末时间
                if (i == 0) {
                    lastMonth = this.lastMonthStartAndEnd(last).some();
                } else {
                    lastMonth = this.lastMonthStartAndEnd(last.minusMonths(1)).some();
                }
                first = lastMonth.get(HmConst.FIRST_DAY);
                last = lastMonth.get(HmConst.LAST_DAY);
                diastolicPressure = this.diastolicPressureListByMonth(customerId, first, last, HmConst.METRIC_TYPE_FASTING).some();
                heartRateOfBP = this.heartRateOfBPListByMonth(customerId, first, last, HmConst.METRIC_TYPE_BEFOREMEAL).some();
                systolicPressure = this.systolicPressureListByMonth(customerId, first, last, HmConst.METRIC_TYPE_NIGHT).some();
                diastolicPressureList.add(diastolicPressure);
                heartRateOfBPList.add(heartRateOfBP);
                systolicPressureList.add(systolicPressure);
            }
            map.put(HmConst.METRIC_TYPE_FASTING,diastolicPressureList);
            map.put(HmConst.METRIC_TYPE_AFTERMEAL,heartRateOfBPList);
            map.put(HmConst.METRIC_TYPE_NIGHT,systolicPressureList);
        }

        return Opt.some(map);
    }

    private Opt<MetricsAnalysisVo> systolicPressureListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countSystolicPressure = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abSystolicPressure = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxSystolicPressure = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minSystolicPressure = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> systolicPressureData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();

        MetricsAnalysisVo mSystolicPressure = new MetricsAnalysisVo();
        mSystolicPressure.setMonth(firstDay.getMonthValue());
        mSystolicPressure.setCountTest(countSystolicPressure);
        mSystolicPressure.setCountAb(abSystolicPressure);
        mSystolicPressure.setMaxValue(maxSystolicPressure);
        mSystolicPressure.setMinValue(minSystolicPressure);
        mSystolicPressure.setCustomerBodyMetricsList(systolicPressureData);
        mSystolicPressure.setMetric(metric);
        return Opt.some(mSystolicPressure);
    }

    private Opt<MetricsAnalysisVo> heartRateOfBPListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countHeartRateOfBP = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 0).some();

        // 异常次数
        Integer abHeartRateOfBP = customerBodyMetricService.countTest(customerId, firstDay, lastDay, metric, 1).some();

        // 最大值
        Double maxHeartRateOfBP = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, metric).some();

        // 最小值
        Double minHeartRateOfBP = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, metric).some();

        // 列表
        List<CustomerBodyMetrics> heartRateOfBPData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, metric).some();


        MetricsAnalysisVo mHeartRateOfBP = new MetricsAnalysisVo();
        mHeartRateOfBP.setMonth(firstDay.getMonthValue());
        mHeartRateOfBP.setCountTest(countHeartRateOfBP);
        mHeartRateOfBP.setCountAb(abHeartRateOfBP);
        mHeartRateOfBP.setMaxValue(maxHeartRateOfBP);
        mHeartRateOfBP.setMinValue(minHeartRateOfBP);
        mHeartRateOfBP.setCustomerBodyMetricsList(heartRateOfBPData);
        mHeartRateOfBP.setMetric(metric);
        return Opt.some(mHeartRateOfBP);
    }

    private Opt<MetricsAnalysisVo> diastolicPressureListByMonth(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric) {
        // 检测数量
        Integer countDiastolicPressure = customerBodyMetricService.countTest(customerId, firstDay, lastDay, "diastolicPressure", 0).some();

        // 异常次数
        Integer abDiastolicPressure = customerBodyMetricService.countTest(customerId, firstDay, lastDay, "diastolicPressure", 1).some();

        // 最大值
        Double maxDiastolicPressure = customerBodyMetricService.getMaxValue(customerId, firstDay, lastDay, "diastolicPressure").some();

        // 最小值
        Double minDiastolicPressure = customerBodyMetricService.getMinValue(customerId, firstDay, lastDay, "diastolicPressure").some();

        // 列表
        List<CustomerBodyMetrics> diastolicPressureData = customerBodyMetricService.findListByIdAndMetric(customerId, firstDay, lastDay, "diastolicPressure").some();

        MetricsAnalysisVo mDiastolicPressure = new MetricsAnalysisVo();
        mDiastolicPressure.setMonth(firstDay.getMonthValue());
        mDiastolicPressure.setCountTest(countDiastolicPressure);
        mDiastolicPressure.setCountAb(abDiastolicPressure);
        mDiastolicPressure.setMaxValue(maxDiastolicPressure);
        mDiastolicPressure.setMinValue(minDiastolicPressure);
        mDiastolicPressure.setCustomerBodyMetricsList(diastolicPressureData);
        mDiastolicPressure.setMetric(metric);

        return Opt.some(mDiastolicPressure);
    }


    @Override
    public Opt<Map<String, Integer>> resultAnalyse(Integer id, String metric) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);

        Map<String, Integer> map = customerBodyMetricService.resultAnalyse(customerId, firstDay, lastDay, metric).some();
        return Opt.some(map);
    }

    @Override
    public Opt<Map<String, Integer>> resultAnalyseWeight(Integer id) {
        return Opt.some(this.resultAnalyse(id, HmConst.METRIC_TYPE_BMI).some());
    }

    @Override
    public Opt<Map<String, Integer>> resultAnalyseBloodGlucose(Integer id) {
        Map<String, Integer> map = new HashMap<>();
        Map<String, Integer> map1 = this.resultAnalyse(id, HmConst.METRIC_TYPE_FASTING).some();
        Map<String, Integer> map2 = this.resultAnalyse(id, HmConst.METRIC_TYPE_BEFOREMEAL).some();
        Map<String, Integer> map3 = this.resultAnalyse(id, HmConst.METRIC_TYPE_AFTERMEAL).some();
        Map<String, Integer> map4 = this.resultAnalyse(id, HmConst.METRIC_TYPE_NIGHT).some();
        map.putAll(map1);
        map.putAll(map2);
        map.putAll(map3);
        map.putAll(map4);
        return Opt.some(map);
    }


    @Override
    public Opt<Map<String, Integer>> resultAnalyseBloodPressure(Integer id) {
        Map<String, Integer> map = new HashMap<>();
        Map<String, Integer> map1 = this.resultAnalyse(id, HmConst.METRIC_TYPE_DIASTOLICPRESSURE).some();
        Map<String, Integer> map2 = this.resultAnalyse(id, HmConst.METRIC_TYPE_HEARTPATEOFBP).some();
        Map<String, Integer> map3 = this.resultAnalyse(id, HmConst.METRIC_TYPE_SYSTOLICPRESSURE).some();
        map.putAll(map1);
        map.putAll(map2);
        map.putAll(map3);
        return Opt.some(map);
    }



    /**
     * 数据来源分析
     * @param id 健康报告ID
     * @param metric 指标名
     * @return key来源,value数量
     */
    public Opt<Map<String, Integer>> sourceAnalyse(Integer id, String metric) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);

        Map<String, Integer> map = customerBodyMetricService.sourceAnalyse(customerId, firstDay, lastDay, metric).some();
        return Opt.some(map);
    }
    @Override
    public Opt<Map<String, Integer>> sourceAnalyseWeight(Integer id) {
        return Opt.some(this.sourceAnalyse(id, HmConst.METRIC_TYPE_WEIGHT).some());
    }

    @Override
    public Opt<Map<String, Integer>> sourceAnalyseBloodGlucose(Integer id) {
        Map<String, Integer> map = new HashMap<>();
        Map<String, Integer> map1 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_FASTING).some();
        Map<String, Integer> map2 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_BEFOREMEAL).some();
        Map<String, Integer> map3 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_AFTERMEAL).some();
        Map<String, Integer> map4 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_NIGHT).some();
        map.putAll(map1);
        map.putAll(map2);
        map.putAll(map3);
        map.putAll(map4);
        return Opt.some(map);
    }

    @Override
    public Opt<Map<String, Integer>> sourceAnalyseBloodPressure(Integer id) {
        Map<String, Integer> map = new HashMap<>();
        Map<String, Integer> map1 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_DIASTOLICPRESSURE).some();
        Map<String, Integer> map2 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_HEARTPATEOFBP).some();
        Map<String, Integer> map3 = this.sourceAnalyse(id, HmConst.METRIC_TYPE_SYSTOLICPRESSURE).some();
        map.putAll(map1);
        map.putAll(map2);
        map.putAll(map3);
        return Opt.some(map);
    }

    /**
     * 时间段测试分析
     * @param id 健康报告ID
     * @param metric 指标名
     * @return key时间段,value次数和数据列表
     */
    public Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyse(Integer id, String metric) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> recordTime = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = recordTime.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = recordTime.get(HmConst.LAST_DAY);

        Map<String, List<MetricsAnalysisVo>> map = new HashMap<>();

        // 0凌晨,1早上,2晚上
        Integer count0 = customerBodyMetricService.timeAnalyse(customerId, firstDay, lastDay, metric, 0).some();
        Integer count1 = customerBodyMetricService.timeAnalyse(customerId, firstDay, lastDay, metric, 1).some();
        Integer count2 = customerBodyMetricService.timeAnalyse(customerId, firstDay, lastDay, metric, 2).some();

        List<MetricsAnalysisVo> voList0 = this.dataByTime(customerId, firstDay, lastDay, metric, 0).some();
        for (MetricsAnalysisVo m : voList0) {
            m.setCountTest(count0);
        }

        List<MetricsAnalysisVo> voList1 = this.dataByTime(customerId, firstDay, lastDay, metric, 1).some();
        for (MetricsAnalysisVo m : voList1) {
            m.setCountTest(count1);
        }

        List<MetricsAnalysisVo> voList2 = this.dataByTime(customerId, firstDay, lastDay, metric, 2).some();
        for (MetricsAnalysisVo m : voList2) {
            m.setCountTest(count2);
        }

        map.put("凌晨",voList0);
        map.put("早上",voList1);
        map.put("晚上",voList2);

        return Opt.some(map);
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseWeight(Integer id) {
        return Opt.some(this.timeAnalyse(id, HmConst.METRIC_TYPE_WEIGHT).some());
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodGlucose(Integer id) {
        return Opt.some(this.timeAnalyse(id, HmConst.METRIC_TYPE_BLOODGLUCOSE).some());
    }

    @Override
    public Opt<Map<String, List<MetricsAnalysisVo>>> timeAnalyseBloodPressure(Integer id) {
        return Opt.some(this.timeAnalyse(id, HmConst.METRIC_TYPE_BLOODPRESSURE).some());
    }

    @Override
    public Opt<List<HealthRecordEntry>> listHealthRecordEntry(Integer id) {

        return  Opt.some(healthRecordDao.listHealthRecordEntry(id));
    }

    @Override
    public Opt<Map<String, List<CommodityAndServiceItemVo>>> findCidsAndSids(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        Map<String, List<CommodityAndServiceItemVo>> map = new HashMap<>();
        List<CommodityAndServiceItemVo> cList = new ArrayList<>();

        if (healthRecordEntity.getCommodityIds().length() > 0){
            String[] commodityIdsArray = healthRecordEntity.getCommodityIds().split(",");
            for (String c: commodityIdsArray) {
                MallShopCommodityEntity commodity = mallShopCommodityDao.getById(c);
                CommodityAndServiceItemVo c1 = new CommodityAndServiceItemVo();
                c1.setId(commodity.getId());
                c1.setType(0);
                c1.setDesc(commodity.getCommodityDetail());
                c1.setName(commodity.getCommodityTitle());
                c1.setHrId(id);
                cList.add(c1);
            }
            map.put("商品", cList);
        }

        List<CommodityAndServiceItemVo> sList = new ArrayList<>();
        if (healthRecordEntity.getServiceItemIds().length() > 0) {
            String[] serviceItemIdsArray = healthRecordEntity.getServiceItemIds().split(",");
            for (String s: serviceItemIdsArray) {
                ServiceItemEntity serviceItem = serviceItemDao.getById(Integer.valueOf(s));
                CommodityAndServiceItemVo s1 = new CommodityAndServiceItemVo();
                s1.setId(String.valueOf(serviceItem.getId()));
                s1.setType(1);
                s1.setDesc(serviceItem.getDescription());
                s1.setName(serviceItem.getName());
                s1.setHrId(id);
                sList.add(s1);
            }
            map.put("服务项目", sList);
        }

        return Opt.some(map);
    }

    @Override
    public Opt<Map<String, Integer>> healthPunch(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        Map<String, Integer> map = new HashMap<>();

        int count = 0;

        count = healthPunchItemDao.getCountByPunchType(customerId, firstDay, lastDay, HmConst.PUNCH_TYPE_FOOD);
        map.put(HmConst.PUNCH_TYPE_FOOD, count);

        count = healthPunchItemDao.getCountByPunchType(customerId, firstDay, lastDay, HmConst.PUNCH_TYPE_SPORT);
        map.put(HmConst.PUNCH_TYPE_SPORT, count);

        count = healthPunchItemDao.getCountByPunchType(customerId, firstDay, lastDay, HmConst.PUNCH_TYPE_SLEEP);
        map.put(HmConst.PUNCH_TYPE_SLEEP, count);

        count = healthPunchItemDao.getCountByPunchType(customerId, firstDay, lastDay, HmConst.PUNCH_TYPE_OTHERS);
        map.put(HmConst.PUNCH_TYPE_OTHERS, count);


        return Opt.some(map);
    }

    @Override
    public Opt<Integer> healthPunchCount(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        return Opt.some(healthPunchItemDao.getCountSum(customerId, firstDay, lastDay));
    }

    @Override
    public Opt<List<CustomerQuestionnaireVo>> questionnaireList(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<CustomerQuestionnaireEntity> list = customerQuestionnaireDao.listByCustomerId(customerId, firstDay, lastDay);
        List<CustomerQuestionnaireVo> voList = new ArrayList<>();
        for (CustomerQuestionnaireEntity c : list) {
            CustomerQuestionnaireVo vo = new CustomerQuestionnaireVo();
            vo.setId(c.getId());
            vo.setCustomerId(customerId);
            vo.setQuestionnaireId(c.getQuestionnaireId());
            vo.setTitle(questionnaireDao.getById(c.getQuestionnaireId()).getTitle());
            vo.setAssessment(c.getAssessment());
            voList.add(vo);
        }
        return Opt.some(voList);
    }

    @Override
    public Opt<Integer> questionnaireCount(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        return Opt.some(customerQuestionnaireDao.getCount(customerId, firstDay, lastDay));
    }

    @Override
    public Opt<Integer> serviceCount(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDate firstDay = LocalDate.from(time.get(HmConst.FIRST_DAY));
        LocalDate lastDay = LocalDate.from(time.get(HmConst.LAST_DAY));


        List<ServiceTaskEntity> list = serviceTaskDao.listByCustomer(customerId, firstDay, lastDay);

        int count  = 0;
        for (ServiceTaskEntity s : list) {
            String[] ids = s.getServiceItemIds().split(",");
            count += ids.length;
        }

        return Opt.some(count);
    }

    @Override
    public Opt<Map<String, Integer>> serviceItemCount(Integer id) {
        Map<String, Integer> map = new HashMap<>();

        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDate firstDay = LocalDate.from(time.get(HmConst.FIRST_DAY));
        LocalDate lastDay = LocalDate.from(time.get(HmConst.LAST_DAY));

        List<ServiceTaskEntity> list = serviceTaskDao.listByCustomer(customerId, firstDay, lastDay);

        for (ServiceTaskEntity s : list) {
            String[] ids = s.getServiceItemIds().split(",");
            for (String sid : ids) {
                String name = serviceItemDao.getById(sid).getName();
                if (map.get(name) == null) {
                    map.put(name, 1);
                } else {
                    map.put(name, map.get(name) + 1);
                }

            }
        }

        return Opt.some(map);
    }

    @Override
    public Opt<BigDecimal> serviceCost(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        if (healthRecordEntity.getOrgId() == null) {
            return null;
        }

        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<MallShopApptOrderEntity> list = mallShopApptOrderDao.listByCustomer(customerId, firstDay, lastDay);

        BigDecimal totalAmount = BigDecimal.valueOf(0);
        for (MallShopApptOrderEntity m : list) {
            totalAmount.add(m.getTotalAmount());
        }

        return Opt.some(totalAmount);
    }

    @Override
    public Opt<Map<String, BigDecimal>> serviceCostList(Integer id) {
        Map<String, BigDecimal> map = new HashMap<>();

        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        if (healthRecordEntity.getOrgId() == null) {
            return null;
        }

        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<MallShopApptOrderEntity> list = mallShopApptOrderDao.listByCustomer(customerId, firstDay, lastDay);

        for (MallShopApptOrderEntity m : list) {
            String itemId = m.getApptItemId();
            String name = serviceItemDao.getById(itemId).getName();
            BigDecimal totalAmount = BigDecimal.valueOf(0);
            totalAmount.add(m.getTotalAmount());
            if (map.get(name) == null) {
                map.put(name,totalAmount);
            }else{
                map.put(name,map.get(name).add(totalAmount));
            }

        }


        return Opt.some(map);
    }

    @Override
    public Opt<Integer> shopCount(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);




        int count = mallShopOrderDao.getCount(customerId, firstDay, lastDay);

        return Opt.some(count);
    }

    @Override
    public Opt<Map<String, Integer>> commodityCount(Integer id) {
        Map<String, Integer> map = new HashMap<>();

        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<MallShopOrderEntity> list = mallShopOrderDao.listByCustomer(customerId, firstDay, lastDay);
        for (MallShopOrderEntity m : list) {


            List<MallShopOrderCommodityEntity> commodityEntities = mallShopOrderCommodityDao.listByOrderId(m.getId());
            for (MallShopOrderCommodityEntity commodity : commodityEntities) {
                String title = commodity.getCommodityTitle();
                Integer cnt = commodity.getCommodityCnt();
                if (map.get(title) == null) {
                    map.put(title, cnt);
                } else {
                    map.put(title, map.get(title) + cnt);
                }
            }
        }
        return Opt.some(map);
    }

    @Override
    public Opt<BigDecimal> shopCost(Integer id) {
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<MallShopOrderEntity> list = mallShopOrderDao.listByCustomer(customerId, firstDay, lastDay);
        BigDecimal total = BigDecimal.valueOf(0);
        for (MallShopOrderEntity m : list) {
            total.add(m.getTotalAmount());
        }

        return Opt.some(total);
    }

    @Override
    public Opt<Map<String, BigDecimal>> shopCostList(Integer id) {
        Map<String, BigDecimal> map = new HashMap<>();

        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        String customerId = healthRecordEntity.getCustomerId();
        Map<String, LocalDateTime> time = healthRecordDao.getRecordTime(id);
        LocalDateTime firstDay = time.get(HmConst.FIRST_DAY);
        LocalDateTime lastDay = time.get(HmConst.LAST_DAY);

        List<MallShopOrderEntity> list = mallShopOrderDao.listByCustomer(customerId, firstDay, lastDay);
        for (MallShopOrderEntity m : list) {
            List<MallShopOrderCommodityEntity> commodityEntities = mallShopOrderCommodityDao.listByOrderId(m.getId());
            for (MallShopOrderCommodityEntity commodity : commodityEntities) {
                String title = commodity.getCommodityTitle();
                Integer cnt = commodity.getCommodityCnt();
                BigDecimal price = commodity.getPrice();
                if (map.get(title) == null) {
                    map.put(title, price.multiply(BigDecimal.valueOf(cnt)));
                } else {
                    map.put(title, map.get(title).add(price.multiply(BigDecimal.valueOf(cnt))));
                }
            }
        }
        return Opt.some(map);
    }

    @Override
    public Opt<List<String>> showWhatData(Integer id) {
        List<String> list = new ArrayList<>();
        HealthRecordEntity healthRecordEntity = healthRecordDao.getById(id);
        Integer itemId = healthRecordEntity.getItemId();
        ServiceItemEntity serviceItemEntity = serviceItemDao.getById(itemId);
        String params = serviceItemEntity.getParams();
        Map paramsMap = JSON.parseObject(params, Map.class);
        String metrics = (String) paramsMap.get(HmConst.METRICS);
        // 指标相关的接口名
        if (metrics.contains(HmConst.METRIC_TYPE_WEIGHT)) {
            list.add("countWeightAndBmi");
            list.add("listWeight");
            list.add("aveWeightAndBmi");
            list.add("adviceWeight");
            list.add("listWeightPackage");
            list.add("resultAnalyseWeight");
            list.add("sourceAnalyseWeight");
            list.add("timeAnalyseWeight");
        }
        if (metrics.contains(HmConst.METRIC_TYPE_BLOODPRESSURE)) {
            list.add("countBloodPressure");
            list.add("listBloodPressure");
            list.add("aveBloodPressure");
            list.add("adviceBloodPressure");
            list.add("listBloodPressurePackage");
            list.add("resultAnalyseBloodPressure");
            list.add("sourceAnalyseBloodPressure");
            list.add("timeAnalyseBloodPressure");
        }
        if (metrics.contains(HmConst.METRIC_TYPE_BLOODGLUCOSE)) {
            list.add("countBloodGlucose");
            list.add("listBloodGlucose");
            list.add("aveBloodGlucose");
            list.add("adviceBloodGlucose");
            list.add("listBloodGlucosePackage");
            list.add("resultAnalyseBloodGlucose");
            list.add("sourceAnalyseBloodGlucose");
            list.add("timeAnalyseBloodGlucose");
        }
        // 购物分析接口
        if (this.shopCount(id).some() > 0) {
            list.add("shopCount");
            list.add("commodityCount");
            list.add("shopCost");
            list.add("shopCostList");
        }
        if (this.questionnaireCount(id).some() > 0) {
            list.add("questionnaireList");
            list.add("questionnaireCount");
        }
        // 通用接口
        list.add("listHealthRecordEntry");
        list.add("findCidsAndSids");
        list.add("healthPunch");

        return Opt.some(list);
    }

    // todo 待完善
    @Override
    public Opt<Boolean> batchDownload(List<Integer> ids, HttpServletRequest request, HttpServletResponse response) {
        //响应头的设置
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        //设置压缩包的名字
        String dates = DateUtil.STANDARD_24H_FORMATTER.format(LocalDateTime.now());//获取时间戳
        String billname = "附件包-"+dates;
        String downloadName = billname+".zip";
        //返回客户端浏览器的版本号、类型
        String agent = request.getHeader("USER-AGENT");
        try {
            //针对IE或者以IE为内核的浏览器:
            if (agent.contains("MSIE")||agent.contains("Trident")) {
                downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
            } else {
                //非IE浏览器的处理:
                downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");

        //设置压缩流:直接写入response,实现边压缩边下载
        ZipOutputStream zipos = null;
        try {
            zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
            //设置压缩方法
            zipos.setMethod(ZipOutputStream.DEFLATED);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //循环将文件写入压缩流
        DataOutputStream os = null;

        //查询数据库获取文件信息
        for (Integer id : ids) {
            HealthRecord healthRecord = this.getOne(id).some();
            //文件路径
            String filePath = documentPath + File.separator;
//            String filePath = documentPath + File.separator + healthRecord.getFilePath();
            System.out.println("filePath==="+filePath);
            File file = new File(filePath);
            if (!file.exists()) {
                System.out.println("文件已不存在");
            }else{
                try {
                    //添加ZipEntry,并ZipEntry中写入文件流
                    String fileName = "healthRecord"+healthRecord.getId();
                    zipos.putNextEntry(new ZipEntry(fileName));
                    os = new DataOutputStream(zipos);
                    InputStream is = new FileInputStream(file);
                    byte[] b = new byte[100];
                    int length = 0;
                    while((length = is.read(b))!= -1){
                        os.write(b, 0, length);
                    }
                    is.close();
                    zipos.closeEntry();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        //关闭流
        try {
            os.flush();
            os.close();
            zipos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Opt.some(true);
    }

    /**
     * 计算本月的始末时间
     * @param lastday 月末时间
     * @return key始/末,value时间LocalDateTime
     */
    public Opt<Map<String, LocalDateTime>> lastMonthStartAndEnd(LocalDateTime lastday) {
        LocalDateTime first = LocalDateTime.of(lastday.getYear(), lastday.getMonthValue(), 1,0,0,0);
        LocalDateTime last = LocalDateTime.of(lastday.getYear(), lastday.getMonthValue(), lastday.getDayOfMonth(),23,59,59);
        Map<String, LocalDateTime> map = new HashMap<>();
        map.put(HmConst.FIRST_DAY, first);
        map.put(HmConst.LAST_DAY, last);
        return Opt.some(map);
    }


    /**
     * 根据早晚凌晨查询数据
     * @param customerId 客户id
     * @param firstDay 本周期开始时间
     * @param lastDay 本周期开始时间
     * @param metric 指标名称
     * @param type 类型 0凌晨,1早上,2晚上
     * @return
     */
    public Opt<List<MetricsAnalysisVo>> dataByTime(String customerId, LocalDateTime firstDay, LocalDateTime lastDay, String metric, Integer type) {
        List<CustomerBodyMetrics> list = customerBodyMetricService.timeAnalyseData(customerId, firstDay, lastDay, metric, type).some();
        List<CustomerBodyMetrics> listA = new ArrayList<>();
        List<CustomerBodyMetrics> listB = new ArrayList<>();
        List<CustomerBodyMetrics> listC = new ArrayList<>();
        List<CustomerBodyMetrics> listD = new ArrayList<>();
        String s1 = null;
        String s2 = null;
        String s3 = null;
        String s4 = null;
        Integer count = customerBodyMetricService.timeAnalyse(customerId, firstDay, lastDay, metric, type).some();
        for (CustomerBodyMetrics cbm : list) {
            if (HmConst.METRIC_TYPE_WEIGHT.equals(metric)) {
                if (HmConst.METRIC_TYPE_WEIGHT.equals(cbm.getMetric())) {
                    listA.add(cbm);
                    s1 = HmConst.METRIC_TYPE_WEIGHT;
                } else if (HmConst.METRIC_TYPE_BMI.equals(cbm.getMetric())) {
                    listB.add(cbm);
                    s2 = HmConst.METRIC_TYPE_BMI;
                }
            } else if (HmConst.METRIC_TYPE_BLOODPRESSURE.equals(metric)) {
                if (HmConst.METRIC_TYPE_DIASTOLICPRESSURE.equals(cbm.getMetric())) {
                    listA.add(cbm);
                    s1 = HmConst.METRIC_TYPE_DIASTOLICPRESSURE;
                } else if (HmConst.METRIC_TYPE_HEARTPATEOFBP.equals(cbm.getMetric())) {
                    listB.add(cbm);
                    s2 = HmConst.METRIC_TYPE_HEARTPATEOFBP;
                } else if (HmConst.METRIC_TYPE_SYSTOLICPRESSURE.equals(cbm.getMetric())) {
                    listC.add(cbm);
                    s3 = HmConst.METRIC_TYPE_SYSTOLICPRESSURE;
                }
            } else if (HmConst.METRIC_TYPE_BLOODGLUCOSE.equals(metric)) {
                if (HmConst.METRIC_TYPE_BGAFTERBREAKFAST.equals(cbm.getMetric())||HmConst.METRIC_TYPE_BGAFTERDINNER.equals(cbm.getMetric())||HmConst.METRIC_TYPE_BGAFTERLUNCH.equals(cbm.getMetric())) {
                    listA.add(cbm);
                    s1 = HmConst.METRIC_TYPE_AFTERMEAL;
                } else if (HmConst.METRIC_TYPE_BGBEFOREDINNER.equals(cbm.getMetric())||HmConst.METRIC_TYPE_BGBEFORELUNCH.equals(cbm.getMetric())) {
                    listB.add(cbm);
                    s2 = HmConst.METRIC_TYPE_BEFOREMEAL;
                } else if (HmConst.METRIC_TYPE_BGBEFOREDAWN.equals(cbm.getMetric())||HmConst.METRIC_TYPE_BGBEFOREBEDTIME.equals(cbm.getMetric())) {
                    listC.add(cbm);
                    s3 = HmConst.METRIC_TYPE_NIGHT;
                } else if (HmConst.METRIC_TYPE_FASTINGBLOODGLUCOSE.equals(cbm.getMetric())) {
                    listD.add(cbm);
                    s4 = HmConst.METRIC_TYPE_FASTING;
                }
            }
        }
        MetricsAnalysisVo m1 = new MetricsAnalysisVo();
        m1.setCountTest(count);
        m1.setMetric(s1);
        m1.setCustomerBodyMetricsList(listA);

        MetricsAnalysisVo m2 = new MetricsAnalysisVo();
        m2.setCountTest(count);
        m2.setMetric(s2);
        m2.setCustomerBodyMetricsList(listB);

        MetricsAnalysisVo m3 = new MetricsAnalysisVo();
        m3.setCountTest(count);
        m3.setMetric(s3);
        m3.setCustomerBodyMetricsList(listC);

        MetricsAnalysisVo m4 = new MetricsAnalysisVo();
        m4.setCountTest(count);
        m4.setMetric(s4);
        m4.setCustomerBodyMetricsList(listD);

        List<MetricsAnalysisVo> voList = new ArrayList<>();
        voList.add(m1);
        voList.add(m2);
        voList.add(m3);
        voList.add(m4);

        return Opt.some(voList);
    }


}

HealthRecordDao

package com.lanxi.hm.dao.hm;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lanxi.basic.model.Opt;
import com.lanxi.basic.model.Page;
import com.lanxi.core.model.CustomerBodyMetrics;
import com.lanxi.hm.model.HealthRecord;
import com.lanxi.hm.model.HealthRecordEntry;
import com.lanxi.hm.model.entity.hm.HealthRecordEntity;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lanxi.hm.model.vo.MetricsAnalysisVo;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 健康报告 服务类
 * </p>
 *
 * @author hrx
 * @since 2022-08-02
 */
public interface HealthRecordDao extends IService<HealthRecordEntity> {

    IPage<HealthRecord> pageHealthRecord(String orgId, String serviceType, String serviceTeam, Integer pushStatus, String consumerName, String buildStart, String buildEnd, String pushStart, String pushEnd, Integer current, Integer pageSize);

    HealthRecord getOneHealthRecord(Integer id);

    /**
     * 获取报告时间
     * @param id 健康报告ID
     * @return 起/始时间,时间值
     */
    Map<String, LocalDateTime> getRecordTime(Integer id);


    List<HealthRecordEntry> listHealthRecordEntry(Integer id);
}

HealthRecordDaoImpl

package com.lanxi.hm.dao.hm.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lanxi.basic.util.StringUtil;
import com.lanxi.core.model.CustomerBodyMetrics;
import com.lanxi.core.model.enums.MessageBizEnum;
import com.lanxi.core.service.CustomerBodyMetricService;
import com.lanxi.hm.constant.HmConst;
import com.lanxi.hm.dao.hm.HealthRecordEntryDao;
import com.lanxi.hm.model.HealthRecord;
import com.lanxi.hm.model.HealthRecordEntry;
import com.lanxi.hm.model.entity.hm.HealthRecordEntity;
import com.lanxi.hm.mapper.hm.HealthRecordMapper;
import com.lanxi.hm.dao.hm.HealthRecordDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lanxi.hm.model.entity.hm.HealthRecordEntryEntity;
import com.lanxi.hm.model.vo.MetricsAnalysisVo;
import com.lanxi.hm.util.AesUtil;
import com.lanxi.hm.util.DateTimeUtil;
import com.lanxi.hm.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * <p>
 * 健康报告 服务实现类
 * </p>
 *
 * @author hrx
 * @since 2022-08-02
 */
@Service
public class HealthRecordDaoImpl extends ServiceImpl<HealthRecordMapper, HealthRecordEntity> implements HealthRecordDao {

    @Autowired
    private HealthRecordEntryDao healthRecordEntryDao;





    @Override
    public IPage<HealthRecord> pageHealthRecord(String orgId, String serviceType, String serviceTeam, Integer pushStatus, String customerName, String buildStart, String buildEnd, String pushStart, String pushEnd, Integer page, Integer size) {

        return baseMapper.pageHealthRecord(new Page<>(page, size), orgId, serviceType, serviceTeam, pushStatus, StringUtil.isEmpty(customerName)?customerName:AesUtil.encrypt(customerName), buildStart, buildEnd, pushStart, pushEnd);

    }

    @Override
    public HealthRecord getOneHealthRecord(Integer id) {
        return baseMapper.getOneHealthRecord(id);
    }



    @Override
    public Map<String, LocalDateTime> getRecordTime(Integer id) {
        HealthRecordEntity healthRecordEntity = this.getById(id);
        String s = healthRecordEntity.getRecordTime();
        String[] split = s.split("~");

        String s0 = split[0].trim();
        String s1 = split[1].trim();
        LocalDate s00 = LocalDate.from(DateTimeUtil.stringToLocalDateTime(s0+" 00:00:00"));
        LocalDate s11 = LocalDate.from(DateTimeUtil.stringToLocalDateTime(s1+" 00:00:00"));
        LocalDateTime firstDay = LocalDateTime.of(s00, LocalTime.of(0, 0, 0));
        LocalDateTime lastDay = LocalDateTime.of(s11, LocalTime.of(23, 59, 59));
        Map<String, LocalDateTime> map = new HashMap<>();
        map.put(HmConst.FIRST_DAY, firstDay);
        map.put(HmConst.LAST_DAY, lastDay);
        return map;
    }

    @Override
    public List<HealthRecordEntry> listHealthRecordEntry(Integer id) {
        HealthRecordEntity healthRecordEntity = this.getById(id);
        LambdaQueryWrapper<HealthRecordEntryEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(HealthRecordEntryEntity::getOrgId, healthRecordEntity.getOrgId());
        List<HealthRecordEntryEntity> list = healthRecordEntryDao.list(wrapper);
        List<HealthRecordEntry> list1 = new ArrayList<>();
        for (HealthRecordEntryEntity hree :list) {
            list1.add(healthRecordEntryDao.parseToHealthRecordEntry(hree));
        }
        return list1;
    }


}

HealthRecordMapper

package com.lanxi.hm.mapper.hm;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lanxi.basic.model.Opt;
import com.lanxi.hm.model.HealthRecord;
import com.lanxi.hm.model.entity.hm.HealthRecordEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 健康报告 Mapper 接口
 * </p>
 *
 * @author hrx
 * @since 2022-08-02
 */
public interface HealthRecordMapper extends BaseMapper<HealthRecordEntity> {


    IPage<HealthRecord> pageHealthRecord(
            Page<HealthRecordEntity> objectPage,
            @Param("orgId") String orgId,
            @Param("serviceType") String serviceType,
            @Param("serviceTeam") String serviceTeam,
            @Param("pushStatus") Integer pushStatus,
            @Param("customerName") String customerName,
            @Param("buildStart") String buildStart,
            @Param("buildEnd") String buildEnd,
            @Param("pushStart") String pushStart,
            @Param("pushEnd") String pushEnd);


    HealthRecord getOneHealthRecord(@Param("id") Integer id);
}

xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lanxi.hm.mapper.hm.HealthRecordMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.lanxi.hm.model.entity.hm.HealthRecordEntity">
        <id column="id" property="id" />
        <result column="hr_id" property="hrId" />
        <result column="customer_id" property="customerId" />
        <result column="team_id" property="teamId" />
        <result column="item_id" property="itemId" />
        <result column="push_cycle" property="pushCycle" />
        <result column="record_time" property="recordTime" />
        <result column="hr_type" property="hrType" />
        <result column="push_status" property="pushStatus" />
        <result column="push_time" property="pushTime" />
        <result column="commodity_ids" property="commodityIds" />
        <result column="service_item_ids" property="serviceItemIds" />
        <result column="remark" property="remark" />
        <result column="org_id" property="orgId" />
        <result column="user_id" property="userId" />
        <result column="tenant_id" property="tenantId" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, hr_id, customer_id, team_id, item_id, push_cycle, record_time, hr_type, push_status, push_time, commodity_ids, service_item_ids, remark, tenant_id,user_id, org_id, create_time, update_time
    </sql>

    <select id="pageHealthRecord" resultType="com.lanxi.hm.model.HealthRecord">
        select
            hr.id,
            hr.hr_id,
            hr.customer_id,
            c.name as customer_name,
            c.service_team_id as team_id,
            st.name as team_name,
            hr.item_id,
            si.name as item_name,
            hr.push_cycle,
            hr.record_time,
            hr.hr_type,
            hr.push_status,
            hr.push_time,
            hr.commodity_ids,
            hr.service_item_ids,
            hr.remark,
            hr.tenant_id,
            hr.user_id,
            hr.org_id,
            hr.create_time,
            hr.update_time
        from
            health_record hr
        left join
            customer c
            on
                hr.customer_id = c.id

        left join
            service_team st
            on
                c.service_team_id = st.id
        left join
            service_item si
            on
                hr.item_id = si.id
        where
            hr.org_id = #{orgId}
        <if test="serviceType != null and serviceType != ''">
            and
            hr.hr_type = #{serviceType}
        </if>
        <if test="serviceTeam != null and serviceTeam != ''">
            and
            c.service_team_id = #{serviceTeam}
        </if>
        <if test="pushStatus != null and pushStatus != ''">
            and
            hr.push_status = #{pushStatus}
        </if>
        <if test="customerName != null and customerName != ''">
            and(
            c.name like CONCAT('%', #{customerName})
            or
            c.name like CONCAT(#{customerName}, '%')
            or
            c.name like CONCAT('%', #{customerName}, '%')
            )
        </if>
        <if test="buildStart != null and buildStart != ''">
            and
            hr.create_time <![CDATA[ >= ]]> #{buildStart}
        </if>
        <if test="buildEnd != null and buildEnd != ''">
            and
            #{buildEnd} <![CDATA[ >= ]]> hr.create_time
        </if>
        <if test="pushStart != null and pushStart != ''">
            and
            hr.push_time <![CDATA[ >= ]]> #{pushStart}
        </if>
        <if test="pushEnd != null and pushEnd != ''">
            and
            #{pushEnd} <![CDATA[ >= ]]> hr.push_time
        </if>
        order by
            push_status asc,
            create_time desc


    </select>
    <select id="getOneHealthRecord" resultType="com.lanxi.hm.model.HealthRecord">
        select
            hr.id,
            hr.hr_id,
            hr.customer_id,
            c.name as customer_name,
            c.service_team_id as team_id,
            st.name as team_name,
            hr.item_id,
            si.name as item_name,
            hr.push_cycle,
            hr.record_time,
            hr.hr_type,
            hr.push_status,
            hr.push_time,
            hr.commodity_ids,
            hr.service_item_ids,
            hr.remark,
            hr.suggest,
            hr.tenant_id,
            hr.user_id,
            hr.org_id,
            hr.create_time,
            hr.update_time
        from
            health_record hr
                left join
            customer c
            on
                hr.customer_id = c.id

                left join
            service_team st
            on
                c.service_team_id = st.id
                left join
            service_item si
            on
                hr.item_id = si.id
        where
            hr.id = #{id}
    </select>

</mapper>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值