package com.ywt.outpatient.controllers;

import com.ywt.biz.common.enums.OrderTypeEnum;
import com.ywt.biz.common.enums.SexEnum;
import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.biz.common.util.StringHelper;
import com.ywt.biz.common.util.serializers.JsonSerializer;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.check_prescription.CheckPrescriptionRequest;
import com.ywt.gapi.check_prescription.CheckPrescriptionResponse;
import com.ywt.gapi.check_prescription.CheckPrescriptionService;
import com.ywt.gapi.doctor.*;
import com.ywt.gapi.drug.*;
import com.ywt.gapi.im.IMService;
import com.ywt.gapi.im.SendResponse;
import com.ywt.gapi.im.SessionMessage;
import com.ywt.gapi.medicalrecord.*;
import com.ywt.gapi.message.MessageService;
import com.ywt.gapi.message.NotifyAfterCreatePrescriptionRequest;
import com.ywt.gapi.order.OrderService;
import com.ywt.gapi.order.SaveRpSessionRequest;
import com.ywt.gapi.user.GetMedicalRecordListByUserIdRequest;
import com.ywt.gapi.user.GetMedicalRecordsDetailRequest;
import com.ywt.gapi.user.GetMedicalRecordsDetailResponse;
import com.ywt.gapi.user.MedicalRecordsDetail;
import com.ywt.gapi.user.*;
import com.ywt.outpatient.api.resp.CheckPrescriptionResp;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.domain.models.enums.DispositionEnum;
import com.ywt.outpatient.domain.models.enums.MedicalModuleTypeEnum;
import com.ywt.outpatient.domain.models.enums.PrescriptionInfoSourceEnum;
import com.ywt.outpatient.service.rpc.common.ServiceResult;
import com.ywt.outpatient.service.web.DrugSrv;
import com.ywt.outpatient.service.web.UserSrv;
import com.ywt.outpatient.service.web.patient.WebUserService;
import com.ywt.outpatient.service.web.prescription.DrugInfo;
import com.ywt.outpatient.service.web.prescription.DrugInfoListData;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController("/medicalRecord")
@RequestMapping({"/medicalRecord"})
public class MedicalRecordController {
    private static Logger logger = LoggerFactory.getLogger(MedicalRecordController.class);

    @Autowired
    private WebUserService userService;

    @DubboReference
    private UserService userServiceBlockingStub;

    @Autowired
    private UserSrv userSrv;

    @DubboReference
    private DoctorService doctorServiceBlockingStub;

    @DubboReference
    private MedicalRecordService medicalRecordServiceBlockingStub;

    @DubboReference
    private DrugService drugServiceBlockingStub;

    @DubboReference
    private MessageService messageServiceBlockingStub;

    @DubboReference
    private IMService imServiceBlockingStub;

    @DubboReference
    private OrderService orderServiceBlockingStub;

    @DubboReference
    private CheckPrescriptionService checkPrescriptionServiceBlockingStub;

    @Autowired
    private DrugSrv drugSrv;

    /**
     * 根据病历ID得到病历详情
     *
     * @param recordId
     * @return
     */
    @Deprecated
    @RequestMapping({"/getMedicalRecordDetail"})
    public @ResponseBody
    BaseResponse getMedicalRecordDetail(@RequestParam(name = "recordId") int recordId) {
        BaseResponse response = new BaseResponse();
        try {
            GetMedicalRecordsDetailRequest req = GetMedicalRecordsDetailRequest.newBuilder().setRecordId(recordId).build();
            GetMedicalRecordsDetailResponse resp = userServiceBlockingStub.getMedicalRecordsDetail(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                MedicalRecordsDetail detail = resp.getDetail();

                if (detail.getUserId() != userService.getCurrentUserId()) {
                    return response.failed(BaseResponse.PARAMETER_ERROR, "病历不存在");
                }

                Map<String, Object> map = new HashMap<>();
                map.put("recordId", detail.getRecordId());
                map.put("userId", detail.getUserId());
                map.put("sex", detail.getSex());
                map.put("strSex", SexEnum.getSexDisplayName(detail.getSex()));
                map.put("age", detail.getAge());
                map.put("mobile", detail.getMobile());
                map.put("desc", detail.getDesc());
                map.put("patientName", detail.getPatientName());
                map.put("imageUrls", detail.getImageUrlList());
                map.put("idNo", detail.getIdNo());

                return response.succeed(map);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getMedicalRecordDetail({}): {}", recordId, e.getMessage(), e);
            return response.failed(BaseResponse.APP_EXCEPTION, e.getMessage());
        }
    }

    /**
     * 得到病历列表
     *
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Deprecated
    @RequestMapping({"/getMedicalRecordList"})
    public @ResponseBody
    BaseResponse getMedicalRecordList(@RequestParam(name = "pageIndex", required = false) Integer pageIndex,
                                      @RequestParam(name = "pageSize", required = false) Integer pageSize) {
        BaseResponse response = new BaseResponse();

        if (pageIndex == null) {
            pageIndex = 1;
        }

        if (pageSize == null) {
            pageSize = 1000;
        }

        try {
            GetMedicalRecordListByUserIdRequest req = GetMedicalRecordListByUserIdRequest.newBuilder()
                    .setUserId(userService.getCurrentUserId())
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .build();
            GetMedicalRecordListByUserIdResponse resp = userServiceBlockingStub.getMedicalRecordListByUserId(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                List<Map<String, Object>> lst = new LinkedList<>();
                List<MedicalRecordsDetail> list = resp.getDetailList();

                for (MedicalRecordsDetail detail : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("recordId", detail.getRecordId());
                    map.put("sex", detail.getSex());
                    map.put("strSex", SexEnum.getSexDisplayName(detail.getSex()));
                    map.put("age", detail.getAge());
                    map.put("patientName", detail.getPatientName());
                    map.put("idNo", detail.getIdNo());

                    lst.add(map);
                }

                Map<String, Object> data = new HashMap<>();
                data.put("list", lst);
                data.put("count", resp.getCount());
                data.put("totalPages", resp.getTotalPages());

                return response.succeed(data);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getMedicalRecordList({}, {}): {}", pageIndex, pageSize, e.getMessage(), e);
            return response.failed(BaseResponse.APP_EXCEPTION, e.getMessage());
        }
    }

    //创建患者病历
    @RequestMapping(value = {"/create"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse create(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        String typeName = (String) reqBody.getOrDefault("typeName", "");
        String desc = (String) reqBody.getOrDefault("desc", "");
        String images = (String) reqBody.getOrDefault("images", "");
        String diagnose = (String) reqBody.getOrDefault("diagnose", "");
        int patientId = (int) reqBody.getOrDefault("patientId", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();

//        if (StringHelper.isNullOrWhiteSpace(typeName)) {
//            return response.failedWithParameterError("病历类型不能为空");
//        }
//        if (typeName.length() > 20) {
//            return response.failedWithParameterError("病历类型不能超过20字");
//        }
        if (StringHelper.isNullOrWhiteSpace(diagnose)) {
            return response.failedWithParameterError("请填写诊断");
        }

        try {
            CreateMedicalRecordsRequest req = CreateMedicalRecordsRequest.newBuilder()
                    .setDiagnose(diagnose)
                    .setTypeName(Checker.getStringValue(typeName))
                    .setDesc(desc)
                    .setImages(images)
                    .setPatientId(patientId)
                    .setDoctorId(doctorId)
                    .build();
            Result result = doctorServiceBlockingStub.createMedicalRecords(req);

            if (result.getCode() == ResultCode.SUCCEED) {
                Map<String, Object> data = new HashMap<>();
                data.put("recordId", Checker.parseInt(result.getValue()));
                return response.succeed(result.getInfo(), data);
            }
            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("create(reqBody-{}, doctorId-{}): {}", reqBody, doctorId, e.getMessage(), e);
            return response.error();
        }
    }

    //修改病历
    @RequestMapping(value = {"/update"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse update(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        String typeName = (String) reqBody.getOrDefault("typeName", "");
        String desc = (String) reqBody.getOrDefault("desc", "");
        String images = (String) reqBody.getOrDefault("images", "");
        String diagnose = (String) reqBody.getOrDefault("diagnose", "");
        int recordId = (int) reqBody.getOrDefault("recordId", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();

//        if (StringHelper.isNullOrWhiteSpace(typeName)) {
//            return response.failed(BaseResponse.PARAMETER_ERROR, "病历类型不能为空");
//        }
//        if (typeName.length() > 20) {
//            return response.failed(BaseResponse.PARAMETER_ERROR, "病历类型不能超过20字");
//        }
        if (StringHelper.isNullOrWhiteSpace(diagnose)) {
            return response.failedWithParameterError("请填写诊断");
        }

        try {
            UpdateMedicalRecordsRequest req = UpdateMedicalRecordsRequest.newBuilder()
                    .setTypeName(typeName)
                    .setDesc(desc)
                    .setImages(images)
                    .setRecordId(recordId)
                    .setDoctorId(doctorId)
                    .setDiagnose(diagnose)
                    .build();
            Result result = doctorServiceBlockingStub.updateMedicalRecords(req);

            if (result.getCode() == ResultCode.SUCCEED) {
                return response.succeed(result.getInfo());
            }
            return response.failedWithAppError(result.getInfo());
        } catch (Exception e) {
            logger.error("update(reqBody-{}, doctorId-{}): {}", reqBody, doctorId, e.getMessage(), e);
            return response.error();
        }
    }

    //根据病历ID得到病历详情
    @RequestMapping(value = {"/detail"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse getDetail(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer recordId = (Integer) reqBody.getOrDefault("recordId", 0);

        if (recordId <= 0) {
            return response.failedWithParameterError("invalid recordId: " + recordId);
        }
        try {
            com.ywt.gapi.doctor.GetMedicalRecordsDetailRequest req = com.ywt.gapi.doctor.GetMedicalRecordsDetailRequest.newBuilder().setRecordId(recordId).build();
            com.ywt.gapi.doctor.GetMedicalRecordsDetailResponse res = doctorServiceBlockingStub.getMedicalRecordsDetail(req);
            Result result = res.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                com.ywt.gapi.doctor.MedicalRecordsDetail detail = res.getDetail();
                Map<String, Object> data = new HashMap<>();
                data.put("recordId", detail.getRecordId());
                data.put("desc", detail.getDesc());
                data.put("typeName", detail.getTypeName());
                data.put("doctorId", detail.getDoctorId());
                data.put("patientId", detail.getPatientId());
                data.put("diagnose", detail.getDiagnose());

                if (detail.getImageUrlList().size() > 0) {
                    data.put("imageUrls", detail.getImageUrlList());
                }
                return response.succeed(data);
            }
            return response.failedWithAppError(result.getInfo());
        } catch (Exception e) {
            logger.error("getDetail(reqBody-{}): {}", reqBody, e.getMessage(), e);
            return response.error();
        }
    }

    /**
     * 得到病历记录
     *
     * @return
     */
    @RequestMapping(value = {"/list"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse getList(@RequestBody Map<String, Object> map) {
        BaseResponse response = new BaseResponse();
        int pageIndex = Checker.getIntegerValue((Integer) map.getOrDefault("pageIndex", 0));
        int pageSize = Checker.getIntegerValue((Integer) map.getOrDefault("pageSize", 0));
        int patientId = Checker.getIntegerValue((Integer) map.getOrDefault("patientId", 0));
        int doctorId = Checker.getIntegerValue((Integer) map.getOrDefault("doctorId", 0));

        if (pageIndex < 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "页码不正确");
        }

        if (pageSize < 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "页大小不正确");
        }

        if (patientId < 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "患者不存在");
        }

        if (doctorId < 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "医生不存在");
        }

        try {
            GetMedicalRecordsDetailListRequest req = GetMedicalRecordsDetailListRequest.newBuilder()
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .setDoctorId(doctorId)
                    .setPatientId(patientId)
                    .build();
            GetMedicalRecordsDetailListResponse resp = doctorServiceBlockingStub.getMedicalRecordsDetailList(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                List<Map<String, Object>> lst = new LinkedList<>();
                List<com.ywt.gapi.doctor.MedicalRecordsDetail> detailList = resp.getDetailList();

                if (detailList != null && detailList.size() > 0) {
                    for (com.ywt.gapi.doctor.MedicalRecordsDetail detail : detailList) {
                        Map<String, Object> item = new HashMap<>();
                        item.put("recordId", detail.getRecordId());
                        item.put("typeName", detail.getTypeName());
                        item.put("createTime", DateUtil.convertTimestampToDateString(detail.getCreateTime(), "yyyy年MM月dd日"));

                        lst.add(item);
                    }
                }

                Map<String, Object> data = new HashMap<>();
                data.put("list", lst);
                data.put("totalPages", resp.getTotalPages());
                data.put("count", resp.getCount());

                GetPatientRequest getPatientRequest = GetPatientRequest.newBuilder()
                        .setPatientId(patientId)
                        .setDoctorId(userSrv.getCurrentUserIdWrapped())
                        .build();
                GetPatientResponse getPatientResponse = doctorServiceBlockingStub.getPatient(getPatientRequest);
                Result result2 = getPatientResponse.getResult();

                if (result2.getCode() == ResultCode.SUCCEED) {
                    Patient patient = getPatientResponse.getPatient();
                    String strSex = "";
                    if (patient.getSex() == SexEnum.Male.getValue() || patient.getSex() == SexEnum.Female.getValue()) {
                        strSex = SexEnum.getSexDisplayName(patient.getSex());
                    }

                    data.put("name", patient.getRealname());
                    data.put("age", patient.getAge());
                    data.put("sex", patient.getSex());
                    data.put("strSex", strSex);
                    data.put("userId", patient.getUserId());
                    data.put("mobile", patient.getMobile());
                    data.put("idCardNo", patient.getIdCardNo());
                }

                return response.succeed("处理成功", data);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getList(): {}", e.getMessage(), e);
            return response.error();
        }
    }


    /**
     * 添加或修改病历模版
     *
     * @return
     */
    @RequestMapping(value = {"/template/save"}, method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse saveTemplate(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer moduleId = (Integer) reqBody.getOrDefault("moduleId", 0);
        String moduleName = (String) reqBody.getOrDefault("moduleName", "");
        String content = (String) reqBody.getOrDefault("content", "");
        Integer type = (Integer) reqBody.getOrDefault("type", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();

        if (Checker.isNone(moduleName)) {
            return response.failed(BaseResponse.APP_ERROR, "模版标题不能为空");
        }

        MedicalModuleTypeEnum typeEnum = MedicalModuleTypeEnum.valueOf(type);
        if (typeEnum == MedicalModuleTypeEnum.UNKNOW) {
            return response.failed(BaseResponse.APP_ERROR, "模版类型不正确");
        }

        if (content == null) {
            content = "";
        }

        try {
            //现病史，体格检查，专科情况，辅助检查全部字数限制1000字；主诉、既往史、过敏史、个人史全部字数限制500字
            if (typeEnum == MedicalModuleTypeEnum.ChiefComplaint ||
                    typeEnum == MedicalModuleTypeEnum.PastMedicalHistory ||
                    typeEnum == MedicalModuleTypeEnum.AllergicHistory ||
                    typeEnum == MedicalModuleTypeEnum.PersonalHistory) {
                if (content.length() > 500) {
                    return response.failed(BaseResponse.APP_ERROR, "字数不能超过500");
                }
            } else {
                if (content.length() > 1000) {
                    return response.failed(BaseResponse.APP_ERROR, "字数不能超过1000");
                }
            }

            AddOrUpdateMedicalModuleRequest request = AddOrUpdateMedicalModuleRequest.newBuilder()
                    .setContext(content)
                    .setDoctorId(doctorId)
                    .setModuleId(moduleId)
                    .setModuleName(moduleName.trim())
                    .setType(type)
                    .build();
            Result result = doctorServiceBlockingStub.addOrUpdateMedicalModule(request);
            if (result.getCode() == ResultCode.SUCCEED) {
                return response.succeed("处理成功");
            }
            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("saveTemplate(): {}", e.getMessage(), e);
            return response.error();
        }
    }

    /**
     * 得到病历模版详情
     *
     * @return
     */
    @RequestMapping(value = {"/template/detail"}, method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse getTemplateDetail(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer moduleId = (Integer) reqBody.getOrDefault("moduleId", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();

        if (moduleId <= 0) {
            return response.failed(BaseResponse.APP_ERROR, "invalid moduleId");
        }

        try {
            GetMedicalModuleDetailRequest req = GetMedicalModuleDetailRequest.newBuilder()
                    .setModuleId(moduleId)
                    .build();
            GetMedicalModuleDetailResponse res = doctorServiceBlockingStub.getMedicalModuleDetail(req);
            Result result = res.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                Map<String, Object> data = new HashMap<>();
                data.put("moduleId", res.getModuleId());
                data.put("moduleName", res.getModuleName());
                data.put("content", res.getContext());
                data.put("type", res.getType());
                data.put("typeStr", res.getTypeStr());
                return response.succeed(data);
            }
            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getTemplateDetail({}): {}", moduleId, e.getMessage(), e);
            return response.error();

        }
    }

    /**
     * 得到医生所有的某一病历模版
     *
     * @return
     */
    @RequestMapping(value = {"/template/list"}, method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse getTemplateList(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer type = (Integer) reqBody.getOrDefault("type", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();

        if (type <= 0) {
            return response.failed(BaseResponse.APP_ERROR, "invalid type");
        }

        try {
            GetAllMedicalModuleRequest req = GetAllMedicalModuleRequest.newBuilder()
                    .setDoctorId(doctorId)
                    .setType(type)
                    .build();

            GetAllMedicalModuleResponse res = doctorServiceBlockingStub.getAllMedicalModule(req);
            Result result = res.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                List<Map<String, Object>> lst = new LinkedList<>();
                List<MedicalModule> moduleList = res.getMedicalModuleList();

                if (!Checker.isNone(moduleList)) {
                    Map<String, Object> map;
                    for (MedicalModule m : moduleList) {
                        map = new HashMap<>();
                        map.put("moduleId", m.getModuleId());
                        map.put("moduleName", m.getModuleName());
                        lst.add(map);
                    }
                }

                Map<String, Object> data = new HashMap<>();
                data.put("content", res.getContext());
                data.put("type", res.getType());
                data.put("typeStr", res.getTypeStr());
                data.put("module", lst);

                return response.succeed(data);
            }
            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getTemplateList({}, {}): {}", type, doctorId, e.getMessage(), e);
            return response.error();

        }
    }

    //获取门诊病历列表
    @RequestMapping(value = {"/outpatient/list"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse getOutpatientMedicalRecordList(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        String hisPatientId = (String) reqBody.getOrDefault("hisPatientId", "");//门诊ID
        Integer pageIndex = (Integer) reqBody.getOrDefault("pageIndex", 0);//页码
        Integer pageSize = (Integer) reqBody.getOrDefault("pageSize", 0);//页大小

        if (StringHelper.isNullOrWhiteSpace(hisPatientId)) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "invalid hisPatientId");
        }
        if (pageIndex < 1) {
            pageIndex = 1;
        }
        if (pageSize < 1) {
            pageSize = 20;
        }

        try {
            GetOutpatientRecordListByHisPatientIdRequest req = GetOutpatientRecordListByHisPatientIdRequest.newBuilder()
                    .setHisPatientId(hisPatientId)
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .build();
            GetOutpatientRecordListByHisPatientIdResponse res = medicalRecordServiceBlockingStub.getOutpatientRecordListByHisPatientId(req);

            if (res.getCode() == ResultCode.SUCCEED_VALUE) {
                List<Map<String, Object>> lst = new LinkedList<>();
                for (MedicalRecord record : res.getMedicalRecordList()) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("admTime", record.getAdmTime());
                    map.put("clinicCode", record.getClinicCode());
                    map.put("hospitalName", record.getHospitalName());
                    map.put("doctorName", record.getDoctorName());
                    map.put("doctorTitle", record.getDoctorTitle());
                    map.put("recordId", record.getRecordId());
                    map.put("createTime", DateUtil.convertTimestampToDateString(record.getCreateTime(), "yyyy年MM月dd日"));
                    lst.add(map);
                }

                Map<String, Object> map = new HashMap<>();
                map.put("count", res.getCount());
                map.put("totalPages", res.getTotalPages());
                map.put("list", lst);
                return response.succeed(map);
            }
            return response.failed(BaseResponse.APP_ERROR, res.getMsg());
        } catch (Exception e) {
            logger.error("getOutpatientMedicalRecordList({}, {}, {}): {}", hisPatientId, pageIndex, pageSize, e.getMessage(), e);
            return response.error();
        }
    }

    //获取门诊病历详情
    @RequestMapping(value = {"/outpatient/detail"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse getOutpatientMedicalRecordDetail(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer recordId = (Integer) reqBody.getOrDefault("recordId", 0);

        if (recordId < 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "invalid recordId");
        }

        try {
            GetMedicalRecordByIdRequest req = GetMedicalRecordByIdRequest.newBuilder()
                    .setRecordId(recordId)
                    .build();
            GetMedicalRecordByIdResponse res = medicalRecordServiceBlockingStub.getMedicalRecordById(req);
            Result result = res.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                com.ywt.gapi.medicalrecord.MedicalRecord detail = res.getMedicalRecord();

                Map<String, Object> data = new HashMap<>();
                String strAdmTime;

                if (!StringHelper.isNullOrEmpty(detail.getAdmTime())) {
                    String pattern;
                    int len = detail.getAdmTime().length();

                    switch (len) {
                        case 19:
                            pattern = "yyyy-MM-dd HH:mm:ss";
                            break;
                        case 10:
                            pattern = "yyyy-MM-dd";
                            break;
                        default:
                            pattern = "yyyy-M-d";
                            break;
                    }

                    Date date = DateUtil.parseDate(detail.getAdmTime(), pattern);
                    strAdmTime = DateUtil.formatDate(date, "yyyy年MM月dd日");
                } else {
                    strAdmTime = DateUtil.convertTimestampToDateString(detail.getCreateTime(), "yyyy年MM月dd日");
                }

                data.put("admTime", detail.getAdmTime());
                data.put("strAdmTime", strAdmTime);
                data.put("hospitalName", detail.getHospitalName());
                data.put("doctorName", detail.getDoctorName());
                data.put("patientName", detail.getPatientName());
                data.put("selfReport", detail.getSelfReport());
                data.put("phyExam", detail.getPhyExam());
                data.put("diagnose", detail.getDiagnose());
                data.put("suggestion", detail.getSuggestion());
                data.put("advice", detail.getAdvice());           //医嘱

                List<Map<String, Object>> laboratoryReportList = new LinkedList<>();
                List<Map<String, Object>> inspectionReportList = new LinkedList<>();

                if (detail.getLaboratoryReportList() != null) {
                    for (com.ywt.gapi.medicalrecord.LaboratoryReport report : detail.getLaboratoryReportList()) {
                        Map<String, Object> item = new HashMap<>();
                        item.put("id", report.getId());
                        item.put("title", report.getInspectionName());
                        item.put("inspectionId", report.getInspectionId());
                        item.put("reportDate", DateUtil.convertTimestampToDateString(report.getInspectionDate(), "yyyy年MM月dd日"));

                        laboratoryReportList.add(item);
                    }
                }

                if (detail.getInspectionReportList() != null) {
                    for (com.ywt.gapi.medicalrecord.InspectionReport report : detail.getInspectionReportList()) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("id", report.getId());
                        map.put("title", report.getReportTitle());
                        map.put("reportId", report.getReportId());
                        map.put("reportDate", DateUtil.convertTimestampToDateString(report.getReportDate(), "yyyy年MM月dd日"));

                        inspectionReportList.add(map);
                    }
                }

                data.put("laboratoryReportList", laboratoryReportList);
                data.put("inspectionReportList", inspectionReportList);
                return response.succeed(data);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getOutpatientMedicalRecordDetail({}): {}", recordId, e.getMessage(), e);
            return response.error();
        }
    }


    /**
     * 医生PC端开处方，添加患者病历以及保存处方单
     * @param reqBody
     * @return
     */
    @RequestMapping(value = {"/online/create"}, method = RequestMethod.POST)
    public BaseResponse createOutpatientMedicalRecord(@RequestBody Map<String, Object> reqBody) {
        BaseResponse baseResponse = new BaseResponse();
        int doctorId = userSrv.getCurrentUserIdWrapped();

        Integer userId = (Integer) reqBody.getOrDefault("userId", 0);
        Integer patientId = (Integer) reqBody.getOrDefault("patientId", 0);
        String patientName = (String) reqBody.getOrDefault("patientName", "");
        Integer patientSex = (Integer) reqBody.getOrDefault("patientSex", 0);
        Integer patientAge = (Integer) reqBody.getOrDefault("patientAge", 0);
        String patientMobile = (String) reqBody.getOrDefault("patientMobile", "");

        String chiefComplaint = (String) reqBody.getOrDefault("chiefComplaint", "");    //主诉
        String presentHistory = (String) reqBody.getOrDefault("presentHistory", "");    //现病史
        String pastHistory = (String) reqBody.getOrDefault("pastHistory", "");          //既往史
        String allergicHistory = (String) reqBody.getOrDefault("allergicHistory", "");  //过敏史
        String personalHistory = (String) reqBody.getOrDefault("personalHistory", "");  //个人史

        String phyExam = (String) reqBody.getOrDefault("phyExam", "");                  //体格检查
        String strBodyTemperature = (String) reqBody.getOrDefault("bodyTemperature", -1);  //病人体温
        String specialCondition = (String) reqBody.getOrDefault("specialCondition", "");//专科情况

        String accessoryExamination = (String) reqBody.getOrDefault("accessoryExamination", "");//辅助检查
        String diagnosis = (String) reqBody.getOrDefault("diagnosis", "");          //诊断
        Integer single = (Integer) reqBody.getOrDefault("single", -1);              //单病种，1-是，0-否
        String diseaseTime = (String) reqBody.getOrDefault("diseaseTime", "");      //发病时间
        Integer disposition = (Integer) reqBody.getOrDefault("disposition", -1);    //病人去向

        Integer treatmentCase = (Integer) reqBody.getOrDefault("treatmentCase", -1);        //抢救病人
        Integer treatmentStatus = (Integer) reqBody.getOrDefault("treatmentStatus", -1);    //是否抢救成功
        String diseaseEvaluation = (String) reqBody.getOrDefault("diseaseEvaluation", "");  //病情评估

        String icdCode = (String) reqBody.getOrDefault("icdCode", "");          //ICD编码
        String management = (String) reqBody.getOrDefault("management", "");    //处置
        String remark = (String) reqBody.getOrDefault("remark", "");
        String drugInfoList = (String) reqBody.getOrDefault("drugInfoList", "");

        String idCardNo = (String) reqBody.getOrDefault("idCardNo", "");//患者身份证号

        Integer orderId = (Integer) reqBody.getOrDefault("orderId", 0);
        String sessionId = (String) reqBody.getOrDefault("sessionId", "");
        Integer prevPreId = (Integer) reqBody.getOrDefault("prevPreId", 0);
        String address = (String) reqBody.getOrDefault("address", "");

//        if (StringHelper.isNullOrWhiteSpace(drugInfoList)) {
//            return baseResponse.failed(BaseResponse.PARAMETER_ERROR, "药品列表不存在");
//        }
        if (userId <= 0) {
            return baseResponse.failedWithParameterError("invalid userId");
        }
        if (StringHelper.isNullOrWhiteSpace(patientName)) {
            return baseResponse.failedWithParameterError("姓名尚未填写");
        }
//        if (StringHelper.isNullOrWhiteSpace(patientMobile)) {
//            return baseResponse.failed(BaseResponse.PARAMETER_ERROR, "手机号码尚未填写");
//        }
//        if (!PhoneNumChecker.isPhoneNum(patientMobile)) {
//            return baseResponse.failed(BaseResponse.PARAMETER_ERROR, "手机号码不正确");
//        }
//        if (patientAge < 1 || patientAge > 130) {
//            return baseResponse.failed(BaseResponse.PARAMETER_ERROR, "年龄不正确");
//        }

        long longDiseaseTime = 0L;
        if (!StringHelper.isNullOrWhiteSpace(diseaseTime)) {
            Date date = DateUtil.parseDate(diseaseTime, "yyyy-MM-dd");

            if (date != null) {
                longDiseaseTime = date.getTime();
            }
        }

        if (StringHelper.isNullOrWhiteSpace(idCardNo)) {
            idCardNo = "";
        }

        double bodyTemperature = Checker.parseDouble(strBodyTemperature, -1);

        try {

            List<String> icdCodeList = (List<String>) reqBody.getOrDefault("icdCodeList", new LinkedList<String>());
            if (Checker.isNone(icdCodeList)) return baseResponse.failedWithParameterError("icd 编码列表不能为空");

            if (!StringHelper.isNullOrWhiteSpace(patientMobile)) {
                UserRequest userRequest = UserRequest.newBuilder()
                        .setPhone(patientMobile.trim())
                        .build();
                UserResponse userResponse = userServiceBlockingStub.findByPhone(userRequest);
                if (userResponse.getResult().getCode() == ResultCode.SUCCEED && userResponse.getUser().getUserid() == doctorId) {
                    return baseResponse.failedWithParameterError("不能为自己开处方");
                }
            }
            // 添加患者病历
            AddMedicalRecordRequest request = AddMedicalRecordRequest.newBuilder()
                    .setPatientId(patientId)
                    .setPatientName(patientName.trim())
                    .setPatientSex(patientSex)
                    .setPatientAge(patientAge)
                    .setPatientMobile(patientMobile.trim())
                    .setChiefComplaint(chiefComplaint)
                    .setPresentHistory(presentHistory)
                    .setPastHistory(pastHistory)
                    .setAllergicHistory(allergicHistory)
                    .setPersonalHistory(personalHistory)
                    .setPhyExam(phyExam)
                    .setBodyTemperature(bodyTemperature)
                    .setSpecialCondition(specialCondition)
                    .setAccessoryExamination(accessoryExamination)
                    .setDiagnosis(diagnosis)
                    .setSingle(single)
                    .setDiseaseTime(longDiseaseTime)
                    .setDisposition(disposition)
                    .setTreatmentCase(treatmentCase)
                    .setTreatmentStatus(treatmentStatus)
                    .setDiseaseEvaluation(diseaseEvaluation)
                    .setIcdCode(icdCode)
                    .setManagement(management)
                    .setDoctorId(doctorId)
                    .setRemark(remark)
                    .setIdCardNo(idCardNo)
                    .setUserId(userId)
                    .build();
            AddMedicalRecordResponse result = doctorServiceBlockingStub.addMedicalRecord(request);
            if (result.getCode() != ResultCode.SUCCEED) {
                return baseResponse.failed(result.getCode().getNumber(), result.getInfo());
            }
            // 病历 id
            int recordId = result.getRecordId();

            DrugInfoListData drugInfoData = JsonSerializer.from(drugInfoList, DrugInfoListData.class);
            if (drugInfoData == null || drugInfoData.getDrugInfoList() == null || drugInfoData.getDrugInfoList().size() == 0) {
                //只添加病历、没有处方
                return baseResponse.succeed();
            }

            //添加处方
            List<DrugUsage> drugUsageList = new LinkedList<>();
            for (DrugInfo drugInfo : drugInfoData.getDrugInfoList()) {
                ServiceResult serviceResult = drugSrv.validateDrugInfo(drugInfo);
                if (!serviceResult.success()) return baseResponse.failedWithParameterError(serviceResult.getMsg());
                DrugUsage drugUsage = DrugUsage.newBuilder()
                        .setDrugId(drugInfo.getDrugId())
                        .setEachDose(drugInfo.getEachDose())
                        .setUsage(drugInfo.getUsage())
                        .setFrequencyCode(drugInfo.getFrequencyCode())
                        .setFrequency(drugInfo.getFrequency())
                        .setCourse(drugInfo.getDays())
                        .setQuantity(drugInfo.getQuantity())
                        .setRemark(Checker.getStringValue(drugInfo.getRemark()))
                        .setGroup(drugInfo.getGroup())
                        .setUsageCode(Checker.getStringValue(drugInfo.getUsageCode()))
                        .build();
                drugUsageList.add(drugUsage);
            }
            // 显式指定该次请求是否回写处方
            boolean isWriteBackSupport = false;
            if (prevPreId > 0) {
                // 修改处方的时候，如果被修改的处方是回写的，无论当前医生的药房设置如何修改，该处方还是要回写
                GetPrescriptionRequest getPrescriptionRequest = GetPrescriptionRequest.newBuilder()
                        .setPreId(prevPreId)
                        .build();
                GetPrescriptionResponse getPrescriptionResponse = drugServiceBlockingStub.getPrescription(getPrescriptionRequest);
                if (getPrescriptionResponse.getCode() == ResultCode.SUCCEED_VALUE) {
                    PrescriptionInfo pi = getPrescriptionResponse.getPrescriptionInfo();
                    if (pi != null) {
                        isWriteBackSupport = !StringHelper.isNullOrEmpty(pi.getHisOeoriOrderId());
                    }
                } else {
                    return baseResponse.failedWithAppError(String.format("无法获取处方信息：%s", getPrescriptionResponse.getInfo()));
                }
            }

            // 开方规则校验
            CheckPrescriptionRequest checkPrescriptionRequest = CheckPrescriptionRequest.newBuilder()
                    .addAllDrugUsages(drugUsageList)
                    .addAllIcdCode(icdCodeList)
                    .setDoctorId(doctorId)
                    .setIsWriteBackSupport(isWriteBackSupport)
                    .build();
            CheckPrescriptionResponse checkPrescriptionResponse = checkPrescriptionServiceBlockingStub.checkPrescription(checkPrescriptionRequest);
            if (checkPrescriptionResponse.getCode() != ResultCode.SUCCEED_VALUE) {
                String msg = Checker.getStringValue(checkPrescriptionResponse.getInfo());
                return baseResponse.failedWithAppError("开方规则校验不通过：" + msg);
            }
            boolean pass = checkPrescriptionResponse.getPass();
            if (!pass) {
                CheckPrescriptionResp resp = new CheckPrescriptionResp();
                resp.setInfo(checkPrescriptionResponse.getInfo());
                resp.setViolation(checkPrescriptionResponse.getViolationList().stream().map(v -> {
                    CheckPrescriptionResp.Violation violation = new CheckPrescriptionResp.Violation();
                    violation.setId(v.getId());
                    violation.setKey(v.getKey());
                    return violation;
                }).collect(Collectors.toList()));
                return baseResponse.succeed(resp);
            }

            String doctorName = "";
            String hospitalName = "";
            String deptName = "";

            int hospitalId = 0;
            int deptId = 0;
            int doctorSignId = 0;
            int pharmacyId = 0;

            GetDoctorRequest getDoctorRequest = GetDoctorRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorResponse getDoctorResponse = doctorServiceBlockingStub.getDoctor(getDoctorRequest);

            if (getDoctorResponse.getResult().getCode() == ResultCode.SUCCEED && getDoctorResponse.getDoctorInfo() != null) {
                DoctorInfo doctorInfo = getDoctorResponse.getDoctorInfo();
                doctorName = doctorInfo.getName();
                hospitalName = doctorInfo.getHospital();
                deptName = doctorInfo.getDept();
                pharmacyId = doctorInfo.getPharmacyId();

                String[] strHospitalIds = doctorInfo.getHospitalIds().split(",");

                for (String strHospitalId : strHospitalIds) {
                    if (StringHelper.isNullOrEmpty(strHospitalId)) {
                        continue;
                    }

                    hospitalId = Checker.parseInt(strHospitalId);
                    if (hospitalId > 0) {
                        break;
                    }
                }
            }

            GetDoctorSignListRequest signListRequest = GetDoctorSignListRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorSignListResponse signListResponse = doctorServiceBlockingStub.getDoctorSignList(signListRequest);
            if (signListResponse.getResult().getCode() == ResultCode.SUCCEED &&
                    signListResponse.getSignsList() != null &&
                    signListResponse.getSignsList().size() > 0) {
                doctorSignId = signListResponse.getSignsList().get(0).getId();
            }

            SavePrescriptionInfoRequest req = SavePrescriptionInfoRequest.newBuilder()
                    .setHospitalId(hospitalId)
                    .setDeptName(deptName)
                    .setSource(PrescriptionInfoSourceEnum.PC.getValue())
                    .setPatientName(patientName.trim())
                    .setPatientSex(patientSex)
                    .setPatientAge(patientAge)
                    .setPatientMobile(patientMobile.trim())
                    .setDiagnosis(diagnosis)
                    .setAllergicHistory(Checker.getStringValue(allergicHistory))
                    .setDescription("")//这里是病情描述，设置为空
                    .setDoctorId(doctorId)
                    .setDoctorName(doctorName)
                    .setDoctorSignId(doctorSignId)
                    .addAllDrugUsage(drugUsageList)
                    .setIdCardNo(idCardNo)
                    .setUserId(userId)
                    .setPatientNo(String.valueOf(patientId))
                    .setFlag(1)
                    .setPharmacyId(pharmacyId)
                    .setMedRecordId(recordId)
                    .setPrevPreId(prevPreId)
                    .addAllIcdCode(icdCodeList)
                    .setAddress(address)
                    .setWriteBack2His(isWriteBackSupport)
                    .build();
            SavePrescriptionInfoResponse res = drugServiceBlockingStub.savePrescriptionInfo(req);

            if (res.getCode() == 0) {
                try {
                    //通知用户
                    if (!StringHelper.isNullOrWhiteSpace(patientMobile)) {
                        NotifyAfterCreatePrescriptionRequest notifyAfterCreatePrescriptionRequest = NotifyAfterCreatePrescriptionRequest.newBuilder()
                                .setDoctorName(doctorName)
                                .setHospitalName(hospitalName)
                                .setPatientMobile(patientMobile)
                                .setPatientName(patientName)
                                .setUserId(userId)
                                .setBizNo(res.getPreBizNo())
                                .setOrderId(res.getOrderId())
                                .setDoctorId(doctorId)
                                .setTerminal(userSrv.getCurrentTerminal())
                                .setPharmacyId(pharmacyId)
                                .build();
                        messageServiceBlockingStub.notifyAfterCreatePrescription(notifyAfterCreatePrescriptionRequest);
                    }
                    if (orderId != null && orderId > 0 && sessionId != null) {
                        //记录处方单从哪个会话聊天窗口开出
                        SaveRpSessionRequest saveRpSessionRequest = SaveRpSessionRequest.newBuilder()
                                .setPreId(res.getPrescriptionId())
                                .setPreBizNo(res.getPreBizNo())
                                .setSessionId(sessionId)
                                .setDoctorId(doctorId)
                                .setUserId(userId)
                                .setPatientId(patientId)
                                .setUnionOrderId(orderId)
                                // 医生PC端开处方的订单类型只有 咨询 一种。
                                .setUnionOrderType(OrderTypeEnum.CONSULT.getValue())
                                .build();
                        orderServiceBlockingStub.saveRpSession(saveRpSessionRequest);
                        SessionMessage message = SessionMessage.newBuilder()
                                .setMessageType(2)
                                .setFromTerminal(userSrv.getCurrentTerminal())
                                .setContent("{\"realityUrl\":\"https://ywt-image.oss-cn-shenzhen.aliyuncs.com/img/chat_prescription.png\",\"thumbnailsurl\":\"https://ywt-image.oss-cn-shenzhen.aliyuncs.com/img/chat_prescription.png?x-oss-process=image/resize,h_180,w_180\",\"largeurl\":\"https://ywt-image.oss-cn-shenzhen.aliyuncs.com/img/chat_prescription.png?x-oss-process=image/resize,h_600,w_800\"}")
                                .setCustom(String.format("{\"biz_type\":4,\"order_id\":%d,\"auto\":1,\"pre_biz_no\":\"%s\",\"pre_order_id\":%d,\"pharmacyId\":%d}", orderId, res.getPreBizNo(), res.getOrderId(), pharmacyId))
                                .setFromUserId(doctorId)
                                .setFromUserName(doctorName)
                                .setToUserId(userId)
                                .setToUserName(patientName)
                                .setTime(System.currentTimeMillis())
                                .setSessionId(sessionId)
                                .build();
                        SendResponse sendResponse = imServiceBlockingStub.sendSessionMessage(message);
                    }
                } catch (Exception e) {
                    logger.error("创建处方单通知用户出错：{}", e.getMessage(), e);
                }


                Map<String, Object> map = new HashMap<>();
                map.put("prescriptionId", res.getPrescriptionId());
                return baseResponse.succeed(map);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, res.getInfo());

        } catch (
                Exception e) {
            logger.error("addMedicalRecord(): {}", e.getMessage(), e);
            return baseResponse.failed(BaseResponse.APP_EXCEPTION, e.getMessage());
        }

    }

    //线上病历详情
    @RequestMapping(value = {"/online/detail"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse getOnlineDetail(@RequestBody Map<String, Object> reqBody) {
        BaseResponse baseResponse = new BaseResponse();
        Integer recordId = (Integer) reqBody.getOrDefault("recordId", 0);

        if (recordId <= 0) {
            return baseResponse.failed(BaseResponse.APP_ERROR, "invalid recordId");
        }

        try {
            GetMedicalRecordsDetailByIdRequest req = GetMedicalRecordsDetailByIdRequest.newBuilder()
                    .setRecordId(recordId)
                    .build();
            GetMedicalRecordsDetailByIdResponse res = doctorServiceBlockingStub.getMedicalRecordsDetailById(req);
            Result result = res.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                Map<String, Object> map = new HashMap<>();
                map.put("patientName", res.getPatientName());
                map.put("patientSex", SexEnum.getSexDisplayName(res.getPatientSex()));
                map.put("patientAge", res.getPatientAge() + "岁");
                map.put("patientMobile", res.getPatientMobile());
                map.put("chiefComplaint", res.getChiefComplaint());//主诉
                map.put("presentHistory", res.getPresentHistory());//现病史
                map.put("pastHistory", res.getPastHistory());//既往史
                map.put("allergicHistory", res.getAllergicHistory());//过敏史
                map.put("personalHistory", res.getPersonalHistory());//个人史
                map.put("phyExam", res.getPhyExam());//体格检查
                map.put("bodyTemperature", res.getBodyTemperature() == -1 ? "" : res.getBodyTemperature()); //病人体温
                map.put("specialCondition", res.getSpecialCondition());//专科情况
                map.put("accessoryExamination", res.getAccessoryExamination());//辅助检查
                map.put("diagnosis", res.getDiagnosis());//诊断
                map.put("single", res.getSingle() == 1 ? "是" : res.getSingle() == 0 ? "否" : "");//单病种，1-是，0-否
                map.put("singleInt", res.getSingle());//单病种，1-是，0-否
                map.put("diseaseTime", res.getDiseaseTime() == -1 ? "" : DateUtil.convertTimestampToDateString(res.getDiseaseTime(), "yyyy年MM月dd日"));//发病时间
                map.put("disposition", res.getDisposition() == -1 ? "" : DispositionEnum.valueOf(res.getDisposition()).getDisplayName());//病人去向
                map.put("dispositionInt", res.getDisposition());//病人去向
                map.put("treatmentCase", res.getTreatmentCase() == 1 ? "是" : res.getTreatmentCase() == 0 ? "否" : "");//抢救病人
                map.put("treatmentCaseInt", res.getTreatmentCase());//抢救病人
                map.put("treatmentStatus", res.getTreatmentStatus() == 1 ? "是" : res.getTreatmentStatus() == 0 ? "否" : "");//是否抢救成功
                map.put("treatmentStatusInt", res.getTreatmentStatus());//是否抢救成功
                map.put("diseaseEvaluation", res.getDiseaseEvaluation());//病情评估
                map.put("icdCode", res.getIcdCode());//ICD编码
                map.put("management", res.getManagement()); //处置
                map.put("doctorName", res.getDoctorName());
                map.put("deptName", res.getDeptName());
                map.put("remark", res.getRemark());
                map.put("createTime", res.getCreateTime() == -1 ? "" : DateUtil.convertTimestampToDateString(res.getCreateTime(), "yyyy年MM月dd日"));
                map.put("clinicCode", "");//流水号
                map.put("medicalCard", "");//就诊卡
                map.put("typeName", "");//病人类型
                map.put("quota", "");//限额
                return baseResponse.succeed(map);
            }
            return baseResponse.failed(BaseResponse.APP_EXCEPTION, result.getInfo());
        } catch (Exception e) {
            logger.error("getOnlineDetail({}): {}", recordId, e.getMessage(), e);
            return baseResponse.error();
        }
    }

    /**
     * 删除病历模版
     *
     * @return
     */
    @RequestMapping(value = {"/template/del"}, method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse deleteTemplate(@RequestBody Map<String, Object> reqBody) {
        BaseResponse response = new BaseResponse();
        Integer tplId = (Integer) reqBody.getOrDefault("tplId", 0);
        int doctorId = userSrv.getCurrentUserIdWrapped();
        if (Checker.getIntegerValue(tplId) <= 0) {
            return response.failedWithParameterError("invalid tplId");
        }

        try {
            DeleteMedicalRecordTemplateRequest req = DeleteMedicalRecordTemplateRequest.newBuilder()
                    .setDoctorId(doctorId)
                    .setId(tplId)
                    .build();
            DeleteMedicalRecordTemplateResponse res = medicalRecordServiceBlockingStub.deleteMedicalRecordTemplate(req);
            if (res.getCode() == ResultCode.SUCCEED_VALUE) {
                return response.succeed();
            }
            return response.failedWithAppError(res.getMsg());
        } catch (Exception e) {
            logger.error("deleteTemplate({}): {}", reqBody, e.getMessage(), e);
            return response.error();
        }
    }
}
