package com.ywt.outpatient.controllers;

import com.ywt.biz.common.constant.YwtCommonRespCode;
import com.ywt.biz.common.exception.YwtCommonException;
import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.biz.common.util.StringHelper;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.med_equip.*;
import com.ywt.gapi.med_equip.Equip;
import com.ywt.gapi.med_equip.EquipDept;
import com.ywt.gapi.med_equip.InspectionItem;
import com.ywt.gapi.med_equip.ReportItem;
import com.ywt.gapi.user.UserRequest;
import com.ywt.gapi.user.UserResponse;
import com.ywt.gapi.user.UserService;
import com.ywt.outpatient.api.medEquip.CreateOrderResp;
import com.ywt.outpatient.api.resp.BaseResponse2;
import com.ywt.outpatient.api.resp.PageListResponse;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.core.utils.BizUtil;
import com.ywt.outpatient.core.utils.CheckUtil;
import com.ywt.outpatient.domain.models.enums.MedEquipSourceEnum;
import com.ywt.outpatient.api.medEquip.*;
import com.ywt.outpatient.service.web.UserSrv;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Walker
 * Created on 2021/7/6
 */
@RestController("/medEquip")
@RequestMapping({"/medEquip"})
public class MedEquipController {
    private final Logger logger = LoggerFactory.getLogger(MedEquipController.class);

    @DubboReference
    MedEquipService medEquipServiceBlockingStub;
    @DubboReference
    LepuService lepuServiceBlockingStub;
    @DubboReference
    UserService userServiceBlockingStub;
    @Autowired
    UserSrv userSrv;

    /**
     * 医生开检查单
     */
    @RequestMapping(value = {"/createOrder"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<CreateOrderResp> createOrder(@RequestBody CreateOrderReq reqData) {
        BaseResponse2<CreateOrderResp> baseResponse = new BaseResponse2<>();
        try {
            int doctorId = userSrv.getCurrentUserIdWrapped();
            String diagnose = Checker.getStringValue(reqData.getDiagnose());
            List<com.ywt.outpatient.api.medEquip.InspectionItem> inspectionItems = reqData.getInspectionItems();
            int doctorSignId = Checker.getIntegerValue(reqData.getDoctorSignId());
            String remark = Checker.getStringValue(reqData.getRemark());
            CheckUtil.ensureLargerThanZero(doctorId, "请登录后操作");
            CheckUtil.ensureLargerThanZero(doctorSignId, "请提交签名");
            CheckUtil.ensureNotEmpty(diagnose, "请补充诊断");
            if (Checker.isNone(inspectionItems)) {
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, "请选择检查");
            }
            CreateOrderResponse response = medEquipServiceBlockingStub.createOrder(CreateOrderRequest.newBuilder()
                    .setDoctorId(doctorId)
                    .setDiagnose(diagnose)
                    .setDoctorSignId(doctorSignId)
                    .setRemark(remark)
                    .addAllInspectionItem(inspectionItems.stream().map(this::marshal).collect(Collectors.toList()))
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                CreateOrderResp resp = new CreateOrderResp();
                resp.setOrderId(response.getOrderId());
                resp.setOrderNo(response.getOrderNo());
                resp.setEquipOrderId(response.getEquipOrderId());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#createOrder(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private InspectionItem marshal(com.ywt.outpatient.api.medEquip.InspectionItem d) {
        return InspectionItem.newBuilder()
                .setId(Checker.getIntegerValue(d.getId()))
                .setCount(Checker.getIntegerValue(d.getCount()))
                .setName(Checker.getStringValue(d.getName()))
                .setSpec(Checker.getStringValue(d.getSpec()))
                .setPrice(Checker.getIntegerValue(d.getPrice()))
                .setRemark(Checker.getStringValue(d.getRemark()))
                .build();
    }

    private com.ywt.outpatient.api.medEquip.InspectionItem unmarshal(InspectionItem i) {
        com.ywt.outpatient.api.medEquip.InspectionItem d = new com.ywt.outpatient.api.medEquip.InspectionItem();
        d.setCount(i.getCount());
        d.setId(i.getId());
        d.setName(i.getName());
        d.setRemark(i.getRemark());
        d.setPrice(i.getPrice());
        d.setSpec(i.getSpec());
        return d;
    }

    /**
     * 查询订单详情
     */
    @RequestMapping(value = {"/queryOrder"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<QueryOrderResp> queryOrder(@RequestBody QueryOrderReq reqData) {
        BaseResponse2<QueryOrderResp> baseResponse = new BaseResponse2<>();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            QueryOrderResponse response = medEquipServiceBlockingStub.queryOrder(QueryOrderRequest.newBuilder()
                    .setOrderId(orderId)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed(unmarshal(response.getOrderInfo()));
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#queryOrder(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private QueryOrderResp unmarshal(OrderInfo d) {
        QueryOrderResp resp = new QueryOrderResp();
        resp.setOrderNo(d.getOrderNo());
        resp.setHospitalName(d.getHospitalName());
        resp.setDoctorName(d.getDoctorName());
        resp.setDeptName(d.getDeptName());
        resp.setPatientName(d.getPatientName());
        resp.setPatientIdCard(d.getPatientIdCard());
        resp.setPatientAge(d.getPatientAge());
        resp.setPatientGender(d.getPatientGender());
        resp.setPatientMobile(d.getPatientMobile());
        resp.setPaymentTime(d.getPaymentTime());
        resp.setDiagnose(d.getDiagnose());
        resp.setInspectionItem(d.getInspectionItemList().stream().map(this::unmarshal).collect(Collectors.toList()));
        resp.setDoctorSignId(d.getDoctorSignId());
        resp.setRemark(d.getRemark());
        resp.setStatus(d.getStatus());
        resp.setStatusStr(d.getStatusStr());
        resp.setPayUrl(d.getPayUrl());
        resp.setEquipCode(d.getEquipCode());
        resp.setSenderName(d.getSenderName());
        resp.setRecyclerName(d.getRecyclerName());
        resp.setRefundApplyDoctor(d.getRefundApplyDoctor());
        resp.setRefundRejectReason(d.getRefundRejectReason());
        resp.setEquipId(d.getEquipId());
        resp.setOrderId(d.getOrderId());
        resp.setCreateTime(d.getCreateTime());
        resp.setTotalPrice(d.getTotalPrice());
        int refundFlag = d.getRefundFlag();
        int allocFlag = d.getAllocFlag();
        int recycleFlag = d.getRecycleFlag();
        resp.setRefundFlag(refundFlag);
        resp.setAllocFlag(allocFlag);
        resp.setRecycleFlag(recycleFlag);
        List<Integer> btnFlags = new ArrayList<>();
        btnFlags.add(refundFlag);
        btnFlags.add(allocFlag);
        btnFlags.add(recycleFlag);
        resp.setBtnFlags(btnFlags);
        resp.setDoctorSignUrl(d.getDoctorSignUrl());
        resp.setEquipOrderId(d.getEquipOrderId());
        resp.setRecCode(d.getRecCode());
        resp.setEquipCodeEditable(d.getEquipCodeEditable());
        resp.setChangedHospitalId(d.getChangedHospitalId());
        resp.setHospitalId(d.getHospitalId());
        return resp;
    }

    /**
     * 查询开检查记录
     */
    @RequestMapping(value = {"/queryOrderRecords"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<PageListResponse<QueryOrderResp>> queryOrderRecords(@RequestBody QueryOrderRecordsReq reqData) {
        BaseResponse2<PageListResponse<QueryOrderResp>> baseResponse = new BaseResponse2<>();
        try {
            int status = Checker.getIntegerValue(reqData.getStatus(), -1);// 不传默认 -1，表示查全部状态
            String startTime = Checker.getStringValue(reqData.getStartTime());
            String endTime = Checker.getStringValue(reqData.getEndTime());
            String keyword = Checker.getStringValue(reqData.getKeyword());
            int userId = userSrv.getCurrentUserIdWrapped();
            if (userId <= 0) return baseResponse.failed(BaseResponse.PARAMETER_ERROR, "请登录后查询");
            int pageIndex = Checker.getIntegerValue(reqData.getPageIndex());
            int pageSize = Checker.getIntegerValue(reqData.getPageSize());
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());// hospitalId = -1 表示查所有医院
            if (hospitalId == 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            if (!StringHelper.isNullOrWhiteSpace(startTime) || !StringHelper.isNullOrWhiteSpace(endTime)) {
                Date st = DateUtil.parseDate(startTime, DateUtil.DADE_FROMAT_YMD);
                Date et = DateUtil.parseDate(endTime, DateUtil.DADE_FROMAT_YMD);
                CheckUtil.ensureNotNull(st, "开始日期格式有误");
                CheckUtil.ensureNotNull(et, "结束日期格式有误");
            }
            QueryOrderRecordsResponse response = medEquipServiceBlockingStub.queryOrderRecords(QueryOrderRecordsRequest.newBuilder()
                    .setStatus(status)
                    .setStartTime(startTime)
                    .setEndTime(endTime)
                    .setUserId(userId)
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .setHospitalId(hospitalId)
                    .setKeyword(keyword)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                PageListResponse<QueryOrderResp> resp = new PageListResponse<>();
                resp.setTotalPages(response.getTotalPage());
                resp.setCount(response.getCount());
                resp.setList(response.getOrderInfoList().stream().map(this::unmarshal).collect(Collectors.toList()));
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#queryOrderRecords(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 查询检查项目
     */
    @RequestMapping(value = {"/queryInspectionItems"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.InspectionItem>> queryInspectionItems(@RequestBody QueryInspectionItemsReq reqData) {
        BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.InspectionItem>> baseResponse = new BaseResponse2<>();
        try {
            String keyword = Checker.getStringValue(reqData.getKeyword());
            int pageIndex = Checker.getIntegerValue(reqData.getPageIndex());
            int pageSize = Checker.getIntegerValue(reqData.getPageSize());
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (hospitalId <= 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            QueryInspectionItemsResponse response = medEquipServiceBlockingStub.queryInspectionItems(QueryInspectionItemsRequest.newBuilder()
                    .setKeyword(keyword)
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .setHospitalId(hospitalId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                PageListResponse<com.ywt.outpatient.api.medEquip.InspectionItem> resp = new PageListResponse<>();
                resp.setTotalPages(response.getTotalPage());
                resp.setCount(response.getCount());
                resp.setList(response.getInspectionItemList().stream().map(this::unmarshal).collect(Collectors.toList()));
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (Exception e) {
            logger.error("MedEquipController#queryInspectionItems(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 查询设备列表
     */
    @RequestMapping(value = {"/queryEquipList"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.Equip>> queryEquipList(@RequestBody QueryEquipListReq reqData) {
        BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.Equip>> baseResponse = new BaseResponse2<>();
        try {
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            int deptId = Checker.getIntegerValue(reqData.getDeptId());
            int pageIndex = Checker.getIntegerValue(reqData.getPageIndex());
            int pageSize = Checker.getIntegerValue(reqData.getPageSize());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            // 前端没有指定医院，首先尝试根据订单信息获取订单所属医院
            if (hospitalId <= 0) {
                int orderId = Checker.getIntegerValue(reqData.getOrderId());
                if (orderId > 0) {
                    QueryOrderResponse response = medEquipServiceBlockingStub.queryOrder(QueryOrderRequest.newBuilder()
                            .setOrderId(orderId)
                            .setUserId(userId)
                            .build());
                    if (response.getCode() == BaseResponse.SUCCEED) {
                        QueryOrderResp orderResp = unmarshal(response.getOrderInfo());
                        int orderHospitalId = orderResp.getChangedHospitalId() > 0 ? orderResp.getChangedHospitalId() : orderResp.getHospitalId();
                        if (orderHospitalId > 0) {
                            hospitalId = orderHospitalId;
                        }
                    } else {
                        logger.warn("MedEquipController#queryEquipList(): 无法获取当前订单信息(userId = {}, orderId = {}): {}", userId, orderId, response.getInfo());
                    }
                }
            }
            // 仍然获取不到医院 id, 从网关获取当前终端判断所属医院
            if (hospitalId <= 0) {
                logger.warn("MedEquipController#queryEquipList(): 根据终端获取医院 id(userId = {})", userId);
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            QueryEquipListResponse response = medEquipServiceBlockingStub.queryEquipList(QueryEquipListRequest.newBuilder()
                    .setHospitalId(hospitalId)
                    .setDeptId(deptId)
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                PageListResponse<com.ywt.outpatient.api.medEquip.Equip> resp = new PageListResponse<>();
                resp.setList(response.getEquipList().stream().map(this::unmarshal).collect(Collectors.toList()));
                resp.setTotalPages(response.getTotalPage());
                resp.setCount(response.getCount());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (Exception e) {
            logger.error("MedEquipController#queryEquipList(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private com.ywt.outpatient.api.medEquip.Equip unmarshal(Equip d) {
        com.ywt.outpatient.api.medEquip.Equip e = new com.ywt.outpatient.api.medEquip.Equip();
        e.setId(d.getId());
        e.setName(d.getName());
        e.setDeptName(d.getDeptName());
        e.setDeptId(d.getDeptId());
        e.setHospitalId(d.getHospitalId());
        e.setStatus(d.getStatus());
        e.setOccupationStatus(d.getOccupationStatus());
        e.setPayCode(d.getPayCode());
        e.setEquipCode(d.getEquipCode());
        return e;
    }

    /**
     * 申请退款
     */
    @RequestMapping(value = {"/applyForRefund"}, method = RequestMethod.POST)
    public BaseResponse applyForRefund(@RequestBody ApplyForRefundReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            String reason = Checker.getStringValue(reqData.getReason());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            CheckUtil.ensureNotEmpty(reason, "请填写申请理由");
            CheckUtil.ensureLargerThanZero(orderId, "订单 id 有误");
            ApplyForRefundResponse response = medEquipServiceBlockingStub.applyForRefund(ApplyForRefundRequest.newBuilder()
                    .setOrderId(orderId)
                    .setReason(reason)
                    .setOperatorId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed();
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#applyForRefund(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 更新订单信息，患者端支付前提交姓名身份证手机号等信息
     */
    @RequestMapping(value = {"/updateOrderInfo"}, method = RequestMethod.POST)
    public BaseResponse updateOrderInfo(@RequestBody UpdateOrderInfoReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            String patientName = Checker.getStringValue(reqData.getPatientName());
            String patientIdCard = Checker.getStringValue(reqData.getPatientIdCard());
            String patientMobile = Checker.getStringValue(reqData.getPatientMobile());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            CheckUtil.ensureLargerThanZero(orderId, "订单 id 有误");
            UpdateOrderInfoResponse response = medEquipServiceBlockingStub.updateOrderInfo(UpdateOrderInfoRequest.newBuilder()
                    .setOrderId(orderId)
                    .setPatientName(patientName)
                    .setPatientIdCard(patientIdCard)
                    .setPatientMobile(patientMobile)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed();
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#updateOrderInfo(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 查询检查报告列表
     */
    @RequestMapping(value = {"/queryReportList"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.ReportItem>> queryReportList(@RequestBody QueryReportListReq reqData) {
        BaseResponse2<PageListResponse<com.ywt.outpatient.api.medEquip.ReportItem>> baseResponse = new BaseResponse2<>();
        try {
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            int pageIndex = Checker.getIntegerValue(reqData.getPageIndex());
            int pageSize = Checker.getIntegerValue(reqData.getPageSize());
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (hospitalId <= 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            QueryReportListResponse response = medEquipServiceBlockingStub.queryReportList(QueryReportListRequest.newBuilder()
                    .setHospitalId(hospitalId)
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                PageListResponse<com.ywt.outpatient.api.medEquip.ReportItem> resp = new PageListResponse<>();
                resp.setCount(response.getCount());
                resp.setTotalPages(response.getTotalPage());
                resp.setList(response.getReportItemList().stream().map(this::unmarshal).collect(Collectors.toList()));
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#queryReportItems(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private com.ywt.outpatient.api.medEquip.ReportItem unmarshal(com.ywt.gapi.med_equip.ReportItem d) {
        com.ywt.outpatient.api.medEquip.ReportItem i = new com.ywt.outpatient.api.medEquip.ReportItem();
        i.setId(d.getId());
        i.setContent(d.getContent());
        i.setPdfUrl(d.getPdfUrl());
        i.setTimeStamp(d.getTimeStamp());
        return i;
    }

    /**
     * 查询检查报告详情
     */
    @RequestMapping(value = {"/queryReportDetail"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<com.ywt.outpatient.api.medEquip.ReportItem> queryReportDetail(@RequestBody QueryReportDetailReq reqData) {
        BaseResponse2<com.ywt.outpatient.api.medEquip.ReportItem> baseResponse = new BaseResponse2<>();
        try {
            int reportId = Checker.getIntegerValue(reqData.getReportId());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            QueryReportDetailResponse response = medEquipServiceBlockingStub.queryReportDetail(QueryReportDetailRequest.newBuilder()
                    .setReportId(reportId)
                    .setUserId(userId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed(unmarshal(response.getReportItem()));
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#queryReportDetail(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 获取设备科室
     */
    @RequestMapping(value = {"/queryEquipDepts"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<List<com.ywt.outpatient.api.medEquip.EquipDept>> queryEquipDepts(@RequestBody QueryEquipDeptsReq reqData) {
        BaseResponse2<List<com.ywt.outpatient.api.medEquip.EquipDept>> baseResponse = new BaseResponse2<>();
        try {
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (hospitalId <= 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            GetEquipDeptListResponse response = medEquipServiceBlockingStub.getEquipDeptList(GetEquipDeptListRequest.newBuilder()
                    .setHospitalId(hospitalId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed(response.getEquipDeptList().stream().map(this::unmarshal).collect(Collectors.toList()));
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (Exception e) {
            logger.error("MedEquipController#queryEquipDepts(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    private com.ywt.outpatient.api.medEquip.EquipDept unmarshal(com.ywt.gapi.med_equip.EquipDept d) {
        com.ywt.outpatient.api.medEquip.EquipDept e = new com.ywt.outpatient.api.medEquip.EquipDept();
        e.setId(d.getId());
        e.setName(d.getName());
        return e;
    }

    /**
     * 确认领取，分配设备
     */
    @RequestMapping(value = {"/allocateEquip"}, method = RequestMethod.POST)
    public BaseResponse allocateEquip(@RequestBody AllocEquipReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            String equipNo = Checker.getStringValue(reqData.getEquipNo());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            CheckUtil.ensureLargerThanZero(orderId, "订单 id 有误");
            CheckUtil.ensureNotEmpty(equipNo, "请选择设备");
            UserRequest req = UserRequest.newBuilder()
                    .setUserid(userId)
                    .build();
            UserResponse resp = userServiceBlockingStub.findByUserId(req);
            if (resp.getResult().getCode() != ResultCode.SUCCEED)
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, String.format("当前用户状态异常(%d)", userId));
            String userName = Checker.getStringValue(resp.getUser().getRealname());
            QueryOrderResponse qoResponse = medEquipServiceBlockingStub.queryOrder(QueryOrderRequest.newBuilder()
                    .setOrderId(orderId)
                    .setUserId(userId)
                    .build());
            if (qoResponse.getCode() != BaseResponse.SUCCEED)
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, String.format("订单状态异常：%s", qoResponse.getInfo()));
            OrderInfo oi = qoResponse.getOrderInfo();
            AllocEquipResponse response = lepuServiceBlockingStub.allocEquip(AllocEquipRequest.newBuilder()
                    .setOrderId(orderId)
                    .setOperatorId(userId)
                    .setEqmtNo(equipNo)
                    .setPatientName(oi.getPatientName())
                    .setAge(oi.getPatientAge())
                    .setSex(oi.getPatientGender())
                    .setMobile(oi.getPatientMobile())
                    .setIdCard(oi.getPatientIdCard())
                    .setOperatorName(userName)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                AllocEquipResp r = new AllocEquipResp();
                r.setWearId(response.getWearId());
                return baseResponse.succeed(r);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#allocateEquip(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 回收设备
     */
    @RequestMapping(value = {"/recycleEquip"}, method = RequestMethod.POST)
    public BaseResponse recycleEquip(@RequestBody AllocEquipReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            int userId = userSrv.getCurrentUserIdWrapped();
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            CheckUtil.ensureLargerThanZero(orderId, "订单 id 有误");
            UserRequest req = UserRequest.newBuilder()
                    .setUserid(userId)
                    .build();
            UserResponse resp = userServiceBlockingStub.findByUserId(req);
            if (resp.getResult().getCode() != ResultCode.SUCCEED)
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, String.format("当前用户状态异常(%d)", userId));
            String userName = Checker.getStringValue(resp.getUser().getRealname());
            QueryOrderResponse qoResponse = medEquipServiceBlockingStub.queryOrder(QueryOrderRequest.newBuilder()
                    .setOrderId(orderId)
                    .setUserId(userId)
                    .build());
            if (qoResponse.getCode() != BaseResponse.SUCCEED)
                throw new YwtCommonException(YwtCommonRespCode.P_ERR, String.format("订单状态异常：%s", qoResponse.getInfo()));
            OrderInfo oi = qoResponse.getOrderInfo();
            RecycleEquipResponse response = lepuServiceBlockingStub.recycleEquip(RecycleEquipRequest.newBuilder()
                    .setOrderId(orderId)
                    .setOperatorId(userId)
                    .setOperatorName(userName)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed();
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#recycleEquip(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 修改设备码
     */
    @RequestMapping(value = {"/changeEquipCode"}, method = RequestMethod.POST)
    public BaseResponse ChangeEquipCode(@RequestBody ChangeEquipCodeReq reqData) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            int orderId = Checker.getIntegerValue(reqData.getOrderId());
            String equipCode = Checker.getStringValue(reqData.getEquipCode());
            int operatorId = Checker.getIntegerValue(reqData.getOperatorId());
            // 默认白云医生公众号
            int source = Checker.getIntegerValue(reqData.getSource(), MedEquipSourceEnum.DOCTOR_MP_NFYYBYFY.getValue());
            String operatorName = Checker.getStringValue(reqData.getOperatorName());
            if (operatorId <= 0) {
                operatorId = userSrv.getCurrentUserIdWrapped();
            }
            ChangeEquipCodeResponse response = medEquipServiceBlockingStub.changeEquipCode(ChangeEquipCodeRequest.newBuilder()
                    .setOrderId(orderId)
                    .setEquipCode(equipCode)
                    .setOperatorId(operatorId)
                    .setSource(source)
                    .setOperatorName(operatorName)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                return baseResponse.succeed();
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (Exception e) {
            logger.error("MedEquipController#changeEquipCode(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }

    /**
     * 获取设备管理员信息
     */
    @RequestMapping(value = {"/getEquipAdminInfo"}, method = RequestMethod.POST)
    public @ResponseBody
    BaseResponse2<GetEquipAdminInfoResp> getEquipAdminInfo(@RequestBody GetEquipAdminInfoReq reqData) {
        BaseResponse2<GetEquipAdminInfoResp> baseResponse = new BaseResponse2<>();
        try {
            int userId = Checker.getIntegerValue(reqData.getUserId());
            int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
            if (userId <= 0) {
                userId = userSrv.getCurrentUserIdWrapped();
            }
            if (hospitalId <= 0) {
                hospitalId = BizUtil.getHospitalIdByTerminalId(userSrv.getCurrentTerminal());
            }
            CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            CheckUtil.ensureLargerThanZero(hospitalId, "请指定医院");
            GetEquipAdminInfoResponse response = medEquipServiceBlockingStub.getEquipAdminInfo(GetEquipAdminInfoRequest.newBuilder()
                    .setUserId(userId)
                    .setHospitalId(hospitalId)
                    .build());
            if (response.getCode() == BaseResponse.SUCCEED) {
                GetEquipAdminInfoResp resp = new GetEquipAdminInfoResp();
                resp.setHospitalName(response.getHospitalName());
                resp.setDeptName(response.getDeptName());
                resp.setDeptId(response.getDeptId());
                resp.setHospitalId(response.getHospitalId());
                resp.setName(response.getName());
                resp.setMobile(response.getMobile());
                resp.setRemark(response.getRemark());
                resp.setStatus(response.getStatus());
                return baseResponse.succeed(resp);
            }
            return baseResponse.failed(BaseResponse.APP_ERROR, response.getInfo());
        } catch (YwtCommonException appMessageException) {
            return baseResponse.error(appMessageException.getMessage());
        } catch (Exception e) {
            logger.error("MedEquipController#getEquipAdminInfo(): {}", e.getMessage(), e);
            return baseResponse.error(e.getMessage());
        }
    }
}
