<?php

namespace App\Services;

use App\Amqp\Producer\AssignPharmacistProducer;
use App\Amqp\Producer\PrescriptionDistributePhProducer;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\BasicBank;
use App\Model\BasicWord;
use App\Model\DiseaseClassExpertise;
use App\Model\DiseaseClassIcd;
use App\Model\DoctorAccount;
use App\Model\DoctorBankCard;
use App\Model\DoctorExpertise;
use App\Model\DoctorInquiryConfig;
use App\Model\DoctorInquiryTime;
use App\Model\DoctorWord;
use App\Model\Hospital;
use App\Model\InquiryCaseProduct;
use App\Model\OrderEvaluation;
use App\Model\OrderInquiry;
use App\Model\OrderInquiryCase;
use App\Model\OrderPrescription;
use App\Model\OrderPrescriptionIcd;
use App\Model\OrderPrescriptionProduct;
use App\Model\OrderProductItem;
use App\Model\Product;
use App\Model\ProductPlatformAmount;
use App\Model\SystemInquiryConfig;
use App\Model\SystemInquiryTime;
use App\Model\User;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
use App\Utils\Mask;
use Extend\Alibaba\Oss;
use Extend\VerifyDun\BankCard;
use Extend\Wechat\Wechat;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class UserDoctorService extends BaseService
{
    /**
     * 获取医生专长列表
     * 身份认证
     * @return array
     */
    public function getAuthDoctorExpertise(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 获取医生已选择专长
        $doctor_selected_expertise = $this->getDoctorSelectedExpertise($user_info['client_user_id']);

        $expertise_ids = [];

        if (!empty($doctor_selected_expertise)) {
            $expertise_ids = array_column($doctor_selected_expertise, 'expertise_id');
        }

        // 获取全部专长
        $fields = [
            'expertise_id',
            'expertise_name',
            'expertise_sort',
        ];
        $disease_class_expertise = DiseaseClassExpertise::getOrderList([], $fields);

        foreach ($disease_class_expertise as &$item) {
            $item['is_selected'] = 0;
            if (in_array($item['expertise_id'], $expertise_ids)) {
                $item['is_selected'] = 1;
            }
        }

        return success($disease_class_expertise);
    }

    /**
     * 获取医生已选择专长
     * @param string $doctor_id
     * @return array
     */
    public function getDoctorSelectedExpertise(string $doctor_id): array
    {
        if (empty($doctor_id)) {
            throw new BusinessException("缺少医生id");
        }

        $params = array();
        $params['doctor_id'] = $doctor_id;
        $doctor_expertise = DoctorExpertise::getDiseaseClassExpertiseList($params);
        if (!empty($doctor_expertise)) {
            foreach ($doctor_expertise as &$data) {
                if (!empty($data['DiseaseClassExpertise'])) {
                    $data['expertise_name'] = $data['DiseaseClassExpertise']['expertise_name'];
                }
                unset($data['DiseaseClassExpertise']);
            }
        }

        return $doctor_expertise->toArray();
    }

    /**
     * 获取医生银行卡
     * @return array
     */
    public function getDoctorBankCard(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $doctor_bank_card = DoctorBankCard::getWithBankOne($params);
        if (empty($doctor_bank_card)) {
            return success();
        }

        $data = array();
        $data['bank_card_id'] = $doctor_bank_card['bank_card_id'];
        $data['bank_img_path'] = addAliyunOssWebsite($doctor_bank_card['BasicBank']['bank_img_path']);
        $data['bank_name'] = $doctor_bank_card['BasicBank']['bank_name'];
        $data['bank_card_code_mask'] = $doctor_bank_card['bank_card_code_mask'];

        unset($doctor_bank_card);

        return success($data);
    }

    /**
     * 获取医生银行卡详情信息
     * @return array
     */
    public function getDoctorBankCardInfo(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $bank_card_id = $this->request->input('bank_card_id');// 医生银行卡id

        // 获取医生详情数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_info_id',
            'doctor_id',
            'card_name',
            'card_num_mask',
        ];
        $user_doctor_info = UserDoctorInfo::getOne($params, $fields);
        if (empty($user_doctor_info)) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先实名认证");
        }

        $result = array();
        $result['info'] = array();
        $result['bank'] = array();

        $info = array();
        $info['card_name'] = $user_doctor_info['card_name'];
        $info['card_num_mask'] = $user_doctor_info['card_num_mask'];

        if (!empty($bank_card_id)) {
            // 获取添加的银行卡信息
            $params = array();
            $params['doctor_id'] = $user_info['client_user_id'];
            $params['bank_card_id'] = $bank_card_id;
            $doctor_bank_card = DoctorBankCard::getWithBankOne($params);
            if (empty($doctor_bank_card)) {
                return fail();
            }

            $bank = array();
            $bank['bank_card_id'] = $doctor_bank_card['bank_card_id'];
            $bank['bank_id'] = $doctor_bank_card['bank_id'];
            $bank['bank_name'] = $doctor_bank_card['BasicBank']['bank_name'];
            $bank['bank_card_code'] = $doctor_bank_card['bank_card_code'];// 银行卡号
            $bank['province_id'] = $doctor_bank_card['province_id'];
            $bank['province'] = $doctor_bank_card['province'];
            $bank['city_id'] = $doctor_bank_card['city_id'];
            $bank['city'] = $doctor_bank_card['city'];
            $bank['county_id'] = $doctor_bank_card['county_id'];
            $bank['county'] = $doctor_bank_card['county'];
        }

        $result['info'] = $info;// 用户数据
        $result['bank'] = $bank ?? [];// 银行卡数据
        return success($result);
    }

    /**
     * 新增绑定医生银行卡
     * @return array
     * @throws GuzzleException
     */
    public function addDoctorBankCard(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $bank_id = $this->request->input('bank_id');
        $bank_card_code = $this->request->input('bank_card_code');
        $province_id = $this->request->input('province_id');
        $city_id = $this->request->input('city_id');
        $county_id = $this->request->input('county_id');

        // 验证银行
        $params = array();
        $params['bank_id'] = $bank_id;
        $basic_bank = BasicBank::getOne($params);
        if (empty($basic_bank)) {
            return fail(HttpEnumCode::HTTP_ERROR, "开户行错误");
        }

        // 验证省市区
        $areaService = new AreaService();
        $area = $areaService->getAreaById($province_id, $city_id, $county_id);
        if (empty($area)) {
            return fail(HttpEnumCode::HTTP_ERROR, "地区选择错误");
        }

        // 获取医生银行卡
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $doctor_bank_card = DoctorBankCard::getOne($params);
        if (!empty($doctor_bank_card)) {
            return fail(HttpEnumCode::HTTP_ERROR, "已绑定银行卡");
        }

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'is_bind_bank',
            'iden_auth_status',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        if ($user_doctor['is_bind_bank'] == 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "已绑定银行卡");
        }

        if ($user_doctor['iden_auth_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先身份认证");
        }

        // 获取医生详情数据
        $params = array();
        $params['doctor_id'] = $user_doctor['doctor_id'];
        $user_doctor_info = UserDoctorInfo::getOne($params);
        if (empty($user_doctor_info)){
            return fail(HttpEnumCode::HTTP_ERROR,"医生详情错误");
        }

        // 处理银行卡掩码
        $bank_card_code_mask = Mask::maskBankCard($bank_card_code);

        // 验证银行卡
        $BankCard = new BankCard();

        $params = array();
        $params['bankCardNo'] = $bank_card_code;
        $params['name'] = $user_doctor_info['card_name'];
        $params['idCardNo'] = $user_doctor_info['card_num'];
        $res = $BankCard->checkBankCard($params);
        if (!empty($res)){
            return fail(HttpEnumCode::HTTP_ERROR,$res);
        }

        Db::beginTransaction();

        try {
            // 新增医生银行卡
            $data = array();
            $data['doctor_id'] = $user_info['client_user_id'];
            $data['bank_id'] = $bank_id;
            $data['bank_card_code'] = $bank_card_code;
            $data['bank_card_code_mask'] = $bank_card_code_mask;
            $data['province_id'] = $province_id;
            $data['province'] = $area['province']['area_name'];
            $data['city_id'] = $city_id;
            $data['city'] = $area['city']['area_name'];
            $data['county_id'] = $county_id;
            $data['county'] = $area['county']['area_name'];
            $doctor_bank_card = DoctorBankCard::addDoctorBankCard($data);
            if (empty($doctor_bank_card)) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR);
            }

            // 修改医生表绑定银行卡状态
            $params = array();
            $params['doctor_id'] = $user_info['client_user_id'];

            $data = array();
            $data['is_bind_bank'] = 1;
            UserDoctor::editUserDoctor($params, $data);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }

        return success();
    }

    /**
     * 更换医生银行卡
     * @return array
     * @throws GuzzleException
     */
    public function putDoctorBankCard(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $bank_card_id = $this->request->route('bank_card_id');
        $bank_id = $this->request->input('bank_id');
        $bank_card_code = $this->request->input('bank_card_code');
        $province_id = $this->request->input('province_id');
        $city_id = $this->request->input('city_id');
        $county_id = $this->request->input('county_id');

        // 获取医生银行卡
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['bank_card_id'] = $bank_card_id;
        $doctor_bank_card = DoctorBankCard::getOne($params);
        if (empty($doctor_bank_card)) {
            return fail();
        }

        // 检测上次修改时间
        $updated_at = strtotime($doctor_bank_card['updated_at']);
        $moonth_start = strtotime(date("Y-m-01")); // 当月开始时间
        $moonth_end = strtotime(date("Y-m-t")); // 当月结束时间

        if ($updated_at >= $moonth_start && $updated_at <= $moonth_end) {
            // 银行卡一月只能修改一次
            return fail(HttpEnumCode::HTTP_ERROR, "银行卡每月只能修改一次");
        }

        // 验证银行
        $params = array();
        $params['bank_id'] = $bank_id;
        $basic_bank = BasicBank::getOne($params);
        if (empty($basic_bank)) {
            return fail(HttpEnumCode::HTTP_ERROR, "开户行错误");
        }

        // 验证省市区
        $areaService = new AreaService();
        $area = $areaService->getAreaById($province_id, $city_id, $county_id);
        if (empty($area)) {
            return fail(HttpEnumCode::HTTP_ERROR, "地区选择错误");
        }

        // 处理银行卡掩码
        $bank_card_code_mask = Mask::maskBankCard($bank_card_code);;

        // 获取医生详情数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $user_doctor_info = UserDoctorInfo::getOne($params);
        if (empty($user_doctor_info)){
            return fail();
        }

        // 验证银行卡
        $BankCard = new BankCard();

        $params = array();
        $params['bankCardNo'] = $bank_card_code;
        $params['name'] = $user_doctor_info['card_name'];
        $params['idCardNo'] = $user_doctor_info['card_num'];
        $res = $BankCard->checkBankCard($params);
        if (!$res){
            return fail(HttpEnumCode::HTTP_ERROR,$res);
        }

        // 修改银行卡
        $params = array();
        $params['bank_card_id'] = $bank_card_id;

        $data = array();
        $data['bank_id'] = $bank_id;
        $data['bank_card_code'] = $bank_card_code;
        $data['bank_card_code_mask'] = $bank_card_code_mask;
        $data['province_id'] = $province_id;
        $data['province'] = $area['province']['area_name'];
        $data['city_id'] = $city_id;
        $data['city'] = $area['city']['area_name'];
        $data['county_id'] = $county_id;
        $data['county'] = $area['county']['area_name'];
        $data['updated_at'] = date('Y-m-d H:i:s', time());
        DoctorBankCard::editDoctorBankCard($params, $data);

        return success();
    }

    /**
     * 获取处方列表
     * @return array
     */
    public function getPrescriptionList(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $pharmacist_audit_status = $this->request->input('pharmacist_audit_status');
        $page = $this->request->input('page', 1);
        $per_page = $this->request->input('per_page', 10);

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        if ($user_doctor['iden_auth_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成身份认证");
        }

        if ($user_doctor['idcard_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成实名认证");
        }

        if ($user_doctor['multi_point_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成多点执业认证");
        }

        // 获取处方数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['pharmacist_audit_status'] = $pharmacist_audit_status;
        $params['is_delete'] = 0;
        $order_prescriptions = OrderPrescription::getWithIcdPage($params,['*'],$page,$per_page);
        if (empty($order_prescriptions)) {
            return success($order_prescriptions);
        }

        // 处理数据
        $result = array();

        foreach ($order_prescriptions['data'] as $order_prescription) {
            $data = array();
            $data['order_prescription_id'] = $order_prescription['order_prescription_id'];
            $data['order_inquiry_id'] = $order_prescription['order_inquiry_id'];
            $data['patient_name'] = $order_prescription['patient_name'];
            $data['patient_sex'] = $order_prescription['patient_sex'];
            $data['patient_age'] = $order_prescription['patient_age'];
            $data['created_at'] = $order_prescription['created_at']; // 开方时间
            $data['pharmacist_audit_status'] = $order_prescription['pharmacist_audit_status'];// 药师审核状态（0:审核中 1:审核成功 2:审核驳回）
            $data['pharmacist_fail_reason'] = $order_prescription['pharmacist_fail_reason'];// 驳回原因
            $data['platform_audit_status'] = $order_prescription['platform_audit_status'];// 处方平台审核状态（0:审核中 1:审核成功 2:审核驳回）
            $data['platform_fail_reason'] = $order_prescription['platform_fail_reason'];// 处方平台驳回原因

            // 获取病例信息
            $params = array();
            $params['order_inquiry_id'] = $order_prescription['order_inquiry_id'];
            $params['status'] = 1;
            $order_inquiry_case = OrderInquiryCase::getOne($params);
            if (empty($order_inquiry_case)) {
                return fail(HttpEnumCode::SERVER_ERROR);
            }

            // 病情描述
            $data['disease_desc'] = $order_inquiry_case['disease_desc'];

            // 患病时长
            if (empty($order_inquiry_case['diagnosis_date'])) {
                $data['diagnosis_date'] = "未知";
            } else {
                $data['diagnosis_date'] = date('Y-m-d', strtotime($order_inquiry_case['diagnosis_date']));
            }

            // 疾病信息
            $data['order_prescription_icd'] = $order_prescription['OrderPrescriptionIcd'] ?? [];

            $result[] = $data;
        }

        unset($order_prescriptions['data']);
        $order_prescriptions['data'] = $result;

        return success($order_prescriptions);
    }

    /**
     * 获取医生个人中心数据
     * @return array
     */
    public function getDoctorCenter(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'user_name',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
            'is_bind_bank',
            'avatar',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        if ($user_doctor['iden_auth_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成身份认证");
        }

        if ($user_doctor['idcard_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成实名认证");
        }

        if ($user_doctor['is_bind_bank'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先绑定结算银行卡");
        }

        $user_doctor = $user_doctor->toArray();

        // 获取医生账户余额-未提现金额
        $DoctorAccountService = new DoctorAccountService();
        $balance_account = $DoctorAccountService->getDoctorBalanceAccount($user_info['client_user_id']);
        if ($balance_account > 0) {
            $balance_account = $balance_account * 0.75;
        }

        // 获取医生当日接诊的订单金额
        $InquiryService = new InquiryService();
        $estimate_income = $InquiryService->getDoctorDayAmountTotal($user_info['client_user_id'], date('Y-m-d', time()));
        if (!empty($estimate_income)) {
            $estimate_income = $estimate_income * 0.75;
        }

        $user_doctor['avatar'] = addAliyunOssWebsite($user_doctor['avatar']);
        $user_doctor['balance_account'] = $balance_account;
        $user_doctor['estimate_income'] = $estimate_income;

        return success($user_doctor);
    }

    /**
     * 获取常用语列表
     * @return array
     */
    public function getDoctorWords(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $words_type = $this->request->input('words_type');

        $result = array();

        // 获取系统常用语
        $params = array();
        $params['basics_words_type'] = $words_type;
        $params['basics_words_status'] = 1;
        $basic_words = BasicWord::getList($params);
        if (!empty($basic_words)) {
            foreach ($basic_words as $item) {
                $data = array();
                $data['words'] = $item['basics_words'];
                $data['doctor_words_id'] = "";
                $data['is_system'] = 1;
                $result[] = $data;
            }
        }

        // 获取医生自定义常用语
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['words_type'] = $words_type;
        $params['words_status'] = 1;
        $doctor_words = DoctorWord::getList($params);
        if (!empty($doctor_words)) {
            foreach ($doctor_words as $item) {
                $data = array();
                $data['words'] = $item['words'];
                $data['doctor_words_id'] = $item['doctor_words_id'];
                $data['is_system'] = 0;
                $result[] = $data;
            }
        }

        return success($result);
    }

    /**
     * 新增常用语列表
     * @return array
     */
    public function addDoctorWords(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $words = $this->request->input('words');
        $words_type = $this->request->input('words_type');

        // 查询是否重复
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['words_type'] = $words_type;
        $params['words'] = $words;
        $doctor_words = DoctorWord::getOne($params);
        if (!empty($doctor_words)) {
            if ($doctor_words['words_status'] == 0) {
                return fail(HttpEnumCode::HTTP_ERROR, "此常用语已被禁用");
            } else {
                return fail(HttpEnumCode::HTTP_ERROR, "请勿重复添加");
            }
        }

        $data = array();
        $data['doctor_id'] = $user_info['client_user_id'];
        $data['words_type'] = $words_type;
        $data['words_status'] = 1;
        $data['sort'] = 0;
        $data['words'] = $words;

        $doctor_words = DoctorWord::addDoctorWord($data);
        if (empty($doctor_words)) {
            return fail(HttpEnumCode::SERVER_ERROR);
        }

        return success();
    }

    /**
     * 删除常用语
     * @return array
     */
    public function deleteDoctorWords(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $doctor_words_id = $this->request->route('doctor_words_id');

        // 查询是否重复
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['doctor_words_id'] = $doctor_words_id;
        $doctor_words = DoctorWord::getOne($params);
        if (empty($doctor_words)) {
            return fail();
        }

        $params = array();
        $params['doctor_words_id'] = $doctor_words['doctor_words_id'];
        DoctorWord::deleteDoctorWord($params);
        return success();
    }

    /**
     * 获取医生评价
     * @return array
     */
    public function getDoctorEvaluationList(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $doctor_id = $this->request->input('doctor_id');
        $evaluation_type = $this->request->input('evaluation_type', 1);
        $page = $this->request->input('page', 1);
        $per_page = $this->request->input('per_page', 10);

        if (empty($user_info)) {
            return fail();
        }

        $params = array();
        $params['doctor_id'] = $doctor_id;

        // 4-5分为好评、3分为中评、2-1分为差评
        if ($evaluation_type == 1) {
            // 全部
            $avg_score_params = [0, 100];
        } elseif ($evaluation_type == 2) {
            // 好评
            $avg_score_params = [80, 100];
        } elseif ($evaluation_type == 3) {
            // 中/差评
            $avg_score_params = [0, 80];
        } else {
            return fail();
        }

        $order_evaluation = OrderEvaluation::getScorePage($params, $avg_score_params,['*'],$page,$per_page);
        if (!empty($order_evaluation['data'])) {
            foreach ($order_evaluation['data'] as &$item) {
                $item['avg_score'] = floor($item['avg_score'] * 0.05);

            }
        }

        // 获取其他类型评论总数
        if ($evaluation_type != 1) {
            // 好评
            $avg_score_params = [80, 100];
            $good_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);

            // 中/差评
            $avg_score_params = [0, 80];
            $bad_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);
        }

        if ($evaluation_type != 2) {
            // 全部+
            $avg_score_params = [0, 100];
            $total_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);

            // 中/差评
            $avg_score_params = [0, 80];
            $bad_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);

        }

        if ($evaluation_type != 3) {
            // 全部+
            $avg_score_params = [0, 100];
            $total_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);

            // 好评
            $avg_score_params = [80, 100];
            $good_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);
        }

        $order_evaluation['total_quantity'] = $total_quantity ?? $order_evaluation['total'];
        $order_evaluation['good_quantity'] = $good_quantity ?? $order_evaluation['total'];
        $order_evaluation['bad_quantity'] = $bad_quantity ?? $order_evaluation['total'];

        return success($order_evaluation);
    }

    /**
     * 获取医生信息
     * @return array
     */
    public function getDoctorCenterInfo(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'user_name',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
            'brief_introduction',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        // 获取医生详情
        $fields = [
            'card_name',
            'card_num_mask',
        ];

        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $user_doctor_info = UserDoctorInfo::getOne($params, $fields);
        if (empty($user_doctor_info)) {
            $user_doctor['card_name'] = "";
            $user_doctor['card_num_mask'] = "";
        } else {
            $user_doctor['card_name'] = $user_doctor_info['card_name'];
            $user_doctor['card_num_mask'] = $user_doctor_info['card_num_mask'];
        }

        return success($user_doctor->toArray());
    }

    /**
     * 获取医生证书信息
     * @return array
     */
    public function getDoctorCret(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        $res = $this->checkDoctorAuth($user_doctor);
        if ($res !== true) {
            return fail(HttpEnumCode::HTTP_ERROR, $res);
        }

        // 获取医生详情
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $user_doctor_info = UserDoctorInfo::getOne($params);
        if (empty($user_doctor_info)) {
            return success();
        }

        $result = array();

        // 医师执业证
        if (!empty($user_doctor_info['license_cert'])) {
            $license_cert = explode(',', $user_doctor_info['license_cert']);
            foreach ($license_cert as &$item) {
                $item = addAliyunOssWebsite($item);
            }
            $result['license_cert'] = $license_cert;
        }

        // 医师职称证
        if (!empty($user_doctor_info['qualification_cert'])) {
            $qualification_cert = explode(',', $user_doctor_info['qualification_cert']);
            foreach ($qualification_cert as &$item) {
                $item = addAliyunOssWebsite($item);
            }
            $result['qualification_cert'] = $qualification_cert;
        }

        // 医师资格证
        if (!empty($user_doctor_info['work_cert'])) {
            $work_cert = explode(',', $user_doctor_info['work_cert']);
            foreach ($work_cert as &$item) {
                $item = addAliyunOssWebsite($item);
            }
            $result['work_cert'] = $work_cert;
        }

        return success($result);
    }

    /**
     * 获取处方详情
     * @return array
     */
    public function getPrescriptionInfo(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_inquiry_id = $this->request->input('order_inquiry_id');
        $order_prescription_id = $this->request->input('order_prescription_id');

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        $res = $this->checkDoctorAuth($user_doctor);
        if ($res !== true) {
            return fail(HttpEnumCode::HTTP_ERROR, $res);
        }

        // 获取患者病例表
        $fields = [
            'inquiry_case_id',
            'name',
            'sex',
            'age',
            'disease_desc',
        ];

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $params['status'] = 1;
        $order_inquiry_case = OrderInquiryCase::getOne($params, $fields);
        if (empty($order_inquiry_case)) {
            return fail(HttpEnumCode::HTTP_ERROR, "患者病例信息错误");
        }

        // 获取用药意向
        $CaseService = new CaseService();
        $inquiry_case_product = $CaseService->getCaseProductlist($order_inquiry_case['inquiry_case_id']);

        if (!empty($order_prescription_id)) {
            // 获取处方数据
            $params = array();
            $params['order_prescription_id'] = $order_prescription_id;
            $order_prescription = OrderPrescription::getOne($params);
            if (empty($order_prescription)) {
                return fail();
            }

            // 订单-商品订单列表
            $OrderPrescriptionService = new OrderPrescriptionService();
            $order_prescription_product = $OrderPrescriptionService->getproductList($order_prescription_id);

            // 获取处方关联疾病表
            $fields = [
                'prescription_icd_id',
                'icd_id',
                'icd_name',
            ];
            $params = array();
            $params['order_prescription_id'] = $order_prescription_id;
            $order_prescription_icd = OrderPrescriptionIcd::getList($params, $fields);
        }

        $result = array();
        $result['inquiry_case_product'] = $inquiry_case_product;// 用药意向
        $result['prescription_product'] = $order_prescription_product ?? [];// 开方药品
        $result['case'] = $order_inquiry_case;// 病例数据
        $result['prescription_icd'] = $order_prescription_icd ?? [];// 处方诊断疾病
        $result['prescription']['doctor_advice'] = $order_prescription['doctor_advice'] ?? "";// 医嘱

        return success($result);
    }

    /**
     * 修改处方
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function putPrescription(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_prescription_id = $this->request->input('order_prescription_id');
        $prescription_icd = $this->request->input('prescription_icd');
        $doctor_advice = $this->request->input('doctor_advice');
        $prescription_product = $this->request->input('prescription_product');

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $user_doctor = UserDoctor::getOne($params);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        $res = $this->checkDoctorAuth($user_doctor);
        if ($res !== true) {
            return fail(HttpEnumCode::HTTP_ERROR, $res);
        }

        // 获取处方数据
        $params = array();
        $params['order_prescription_id'] = $order_prescription_id;
        $params['doctor_id'] = $user_info['client_user_id'];
        $order_prescription = OrderPrescription::getOne($params);
        if (empty($order_prescription)) {
            return fail();
        }

        // 检测处方状态
        if ($order_prescription['prescription_status'] == 4) {
            // 已使用
            return fail(HttpEnumCode::HTTP_ERROR, "处方已使用，无法更改");
        }

        if ($order_prescription['is_delete'] == 1) {
            // 已使用
            return fail(HttpEnumCode::HTTP_ERROR, "处方已删除，无法更改");
        }

        Db::beginTransaction();

        try {
            // 修改订单-处方表
            $params = array();
            $params['order_prescription_id'] = $order_prescription_id;

            $data = array();
            $data['prescription_status'] = 1; // 处方状态（1:待审核 3:待使用 4:已失效 5:已使用）
            $data['pharmacist_fail_reason'] = ""; // 药师审核驳回原因
            $data['platform_audit_status'] = 0; // 处方平台审核状态（0:审核中 1:审核成功 2:审核驳回）
            $data['platform_fail_reason'] = ""; // 处方平台驳回原因
            $data['doctor_created_time'] = date('Y-m-d H:i:s',time());
            if ($order_prescription['doctor_advice'] != $doctor_advice) {
                $data['doctor_advice'] = $doctor_advice; // 医嘱
            }

            OrderPrescription::edit($params, $data);

            // 删除订单-处方关联疾病表
            $params = array();
            $params['order_prescription_id'] = $order_prescription_id;
            OrderPrescriptionIcd::deleteOrderPrescriptionIcd($params);

            // 处方疾病数据
            foreach ($prescription_icd as $item) {
                // 获取疾病信息
                $params = array();
                $params['icd_id'] = $item;
                $disease_class_icd = DiseaseClassIcd::getOne($params);
                if (empty($disease_class_icd)) {
                    Db::rollBack();
                    return fail();
                }

                // 新增处方疾病
                $data = array();
                $data['order_prescription_id'] = $order_prescription_id;
                $data['icd_id'] = $item;
                $data['icd_name'] = $disease_class_icd['icd_name'];
                $data['icd_code'] = $disease_class_icd['icd_code'];
                $order_prescription_icd = OrderPrescriptionIcd::addOrderPrescriptionIcd($data);
                if (empty($order_prescription_icd)) {
                    Db::rollBack();
                    return fail();
                }

                unset($disease_class_icd);
            }

            // 删除订单-处方药品表
            $params = array();
            $params['order_prescription_id'] = $order_prescription_id;
            OrderPrescriptionProduct::deleteOrderPrescriptionProduct($params);

            // 处方商品数据
            foreach ($prescription_product as $item) {
                // 获取商品数据
                $params = array();
                $params['product_id'] = $item['product_id'];
                $product = Product::getWithAmountOne($params);
                if (empty($product)) {
                    Db::rollBack();
                    return fail();
                }

                if (empty($product['ProductPlatformAmount'])) {
                    // 无药品库存数据
                    Db::rollBack();
                    return fail();
                }

                // 检测药品库存数据
                if ($item['prescription_product_num'] > $product['ProductPlatformAmount']['stock']) {
                    // 库存不足
                    Db::rollBack();
                    return fail(HttpEnumCode::HTTP_ERROR, "药品" . $product['product_name'] . "库存不足");
                }

                // 新增订单-处方药品表
                $data = array();
                $data['order_prescription_id'] = $order_prescription_id;
                $data['product_id'] = $item['product_id'];
                $data['prescription_product_num'] = $item['prescription_product_num'];
                $data['product_name'] = $product['product_name'];
                $data['product_spec'] = $product['product_spec'];
                $data['license_number'] = $product['license_number'];
                $data['manufacturer'] = $product['manufacturer'];
                $data['single_unit'] = $item['single_unit'] ?? $product['single_unit'];
                $data['single_use'] = $item['single_use'] ?? $product['single_use'];
                $data['packaging_unit'] = $item['packaging_unit'] ?? $product['packaging_unit'];
                $data['frequency_use'] = $item['frequency_use'] ?? $product['frequency_use'];
                $data['available_days'] = $item['available_days'] ?? $product['available_days'];
                $order_prescription_product = OrderPrescriptionProduct::addOrderPrescriptionProduct($data);
                if (empty($order_prescription_product)) {
                    Db::rollBack();
                    return fail();
                }

                unset($product);
            }

            $OrderPrescriptionService = new OrderPrescriptionService();
            $prescription_img = $OrderPrescriptionService->openPrescription($order_prescription->order_prescription_id,$user_info['user_id']);
            if (empty($prescription_img)){
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "处方开具失败");
            }

            // 修改处方表
            $data = array();
            $data['prescription_img'] = $prescription_img;
            $data['doctor_created_time'] = date('Y-m-d H:i:s',time());

            $params = array();
            $params['order_prescription_id'] = $order_prescription['order_prescription_id'];
            OrderPrescription::edit($params,$data);

            // 加入分配药师队列
            $data = array();
            $data['order_prescription_id'] = $order_prescription_id;

            $message = new AssignPharmacistProducer($data);
            $producer = ApplicationContext::getContainer()->get(Producer::class);
            $result = $producer->produce($message);
            if (!$result) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR);
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }

        return success();
    }

    /**
     * 新增处方
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function addPrescription(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_inquiry_id = $this->request->input('order_inquiry_id');
        $prescription_icd = $this->request->input('prescription_icd');
        $doctor_advice = $this->request->input('doctor_advice');
        $prescription_product = $this->request->input('prescription_product');

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $user_doctor = UserDoctor::getOne($params);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        $res = $this->checkDoctorAuth($user_doctor);
        if ($res !== true) {
            return fail(HttpEnumCode::HTTP_ERROR, $res);
        }

        // 获取问诊订单数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['order_inquiry_id'] = $order_inquiry_id;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail();
        }

        if (in_array($order_inquiry['inquiry_status'], [1, 2, 3, 6, 7])) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            return fail(HttpEnumCode::HTTP_ERROR, "订单无法开具处方");
        }

        // 检测处方是否重复开具
        $params = array();
        $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
        $params['doctor_id'] = $user_info['client_user_id'];
        $order_prescription = OrderPrescription::getOne($params);
        if (!empty($order_prescription)) {
            return fail(HttpEnumCode::HTTP_ERROR, "订单已开具处方，无法重复开具");
        }

        Db::beginTransaction();
        $generator = $this->container->get(IdGeneratorInterface::class);

        try {
            // 新增处方表
            $data = array();
            $data['order_inquiry_id'] = $order_inquiry_id;
            $data['doctor_id'] = $user_info['client_user_id'];
            $data['patient_id'] = $order_inquiry['patient_id'];
            $data['family_id'] = $order_inquiry['family_id'];
            $data['prescription_status'] = 1;
            $data['doctor_created_time'] = date('Y-m-d H:i:s',time());
            $data['prescription_code'] = $generator->generate(); // 处方编号
            $data['doctor_name'] = $user_doctor['user_name']; // 医生名称
            $data['patient_name'] = $order_inquiry['patient_name'];
            $data['patient_sex'] = $order_inquiry['patient_sex'];
            $data['patient_age'] = $order_inquiry['patient_age'];
            $data['doctor_advice'] = $doctor_advice;
            $order_prescription = OrderPrescription::addOrderPrescription($data);
            if (empty($order_prescription)) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "处方开具失败");
            }

            // 疾病数据
            foreach ($prescription_icd as $item) {
                // 获取疾病信息
                $params = array();
                $params['icd_id'] = $item;
                $disease_class_icd = DiseaseClassIcd::getOne($params);
                if (empty($disease_class_icd)) {
                    Db::rollBack();
                    return fail();
                }

                // 新增处方疾病
                $data = array();
                $data['order_prescription_id'] = $order_prescription['order_prescription_id'];
                $data['icd_id'] = $item;
                $data['icd_name'] = $disease_class_icd['icd_name'];
                $data['icd_code'] = $disease_class_icd['icd_code'];
                $order_prescription_icd = OrderPrescriptionIcd::addOrderPrescriptionIcd($data);
                if (empty($order_prescription_icd)) {
                    Db::rollBack();
                    return fail();
                }

                unset($disease_class_icd);
            }

            // 商品数据
            foreach ($prescription_product as $item) {
                // 获取商品数据
                $params =array();
                $params['product_id'] = $item['product_id'];
                $product = Product::getOne($params);
                if (empty($product)){
                    return fail(HttpEnumCode::SERVER_ERROR,"商品错误");
                }

                // 获取商品库存
                $params =array();
                $params['product_platform_id'] = $product['product_platform_id'];
                $product_platform_amount = ProductPlatformAmount::getOne($params);
                if (empty($product_platform_amount)) {
                    // 无药品库存数据
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR,"无药品库存数据");
                }

                if ($product_platform_amount['stock'] <= 0){
                    return fail(HttpEnumCode::HTTP_ERROR,"商品库存不足");
                }

                // 检测药品库存数据
                if ($item['prescription_product_num'] > $product['ProductPlatformAmount']['stock']) {
                    // 库存不足
                    Db::rollBack();
                    return fail(HttpEnumCode::HTTP_ERROR, "药品" . $product['product_name'] . "库存不足");
                }

                // 新增订单-处方药品表
                $data = array();
                $data['order_prescription_id'] = $order_prescription['order_prescription_id'];
                $data['product_id'] = $item['product_id'];
                $data['prescription_product_num'] = $item['prescription_product_num'];
                $data['product_name'] = $product['product_name'];
                $data['product_spec'] = $product['product_spec'];
                $data['license_number'] = $product['license_number'];
                $data['manufacturer'] = $product['manufacturer'];
                $data['single_unit'] = $item['single_unit'] ?? $product['single_unit'];
                $data['single_use'] = $item['single_use'] ?? $product['single_use'];
                $data['packaging_unit'] = $item['packaging_unit'] ?? $product['packaging_unit'];
                $data['frequency_use'] = $item['frequency_use'] ?? $product['frequency_use'];
                $data['available_days'] = $item['available_days'] ?? $product['available_days'];
                $order_prescription_product = OrderPrescriptionProduct::addOrderPrescriptionProduct($data);
                if (empty($order_prescription_product)) {
                    Db::rollBack();
                    return fail();
                }

                unset($product);
            }

            $OrderPrescriptionService = new OrderPrescriptionService();
            $prescription_img = $OrderPrescriptionService->openPrescription($order_prescription->order_prescription_id,$user_info['user_id']);
            if (empty($prescription_img)){
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "处方开具失败");
            }

            // 修改处方表
            $data = array();
            $data['prescription_img'] = $prescription_img;
            $data['doctor_created_time'] = date('Y-m-d H:i:s',time());

            $params = array();
            $params['order_prescription_id'] = $order_prescription->order_prescription_id;
            OrderPrescription::edit($params,$data);

            // 加入分配药师队列
            $data = array();
            $data['order_prescription_id'] = $order_prescription['order_prescription_id'];

            $message = new AssignPharmacistProducer($data);
            $producer = ApplicationContext::getContainer()->get(Producer::class);
            $result = $producer->produce($message);
            if (!$result) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR);
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }

        return success();
    }

    /**
     * 获取医生名片
     * @throws NotFoundExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ContainerExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws ClientExceptionInterface
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     */
    public function getDoctorInfoCard(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 获取医生信息
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];

        $fields = [
            'doctor_id',
            'user_name',
            'avatar',
            'doctor_title',
            'department_custom_name',
            'iden_auth_status',
            'idcard_status',
            'multi_point_status',
            'hospital_id',
            'qr_code',
            'is_bind_bank',
        ];
        $user_doctor = UserDoctor::getOne($params, $fields);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法医生");
        }

        if ($user_doctor['iden_auth_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成身份认证");
        }

        if ($user_doctor['idcard_status'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先完成实名认证");
        }

        if ($user_doctor['is_bind_bank'] != 1) {
            return fail(HttpEnumCode::HTTP_ERROR, "请先绑定结算银行卡");
        }

        // 获取医生医院
        $params = array();
        $params['hospital_id'] = $user_doctor['hospital_id'];
        $hospital = Hospital::getOne($params);
        if (empty($hospital)) {
            return fail();
        }

        // 获取医生分享二维码
        $qr_code = $user_doctor['qr_code'];
        if (empty($qr_code)){
            $weChat = new Wechat(1);

            $options = [
                "scene" => "doctor_id=" . $user_doctor['doctor_id'],// query 参数
                "page" => "",
                "check_path" => false,
                "env_version" => "develop",
            ];

            $img_buffer = $weChat->getUnlimitedQRCode($options);

            $oss = new Oss();

            $filename = "applet/doctor/card/" . $user_doctor['doctor_id'] . '.' . 'jpg';

            $qr_code = $oss->putObject($filename, $img_buffer);

            // 存储至医生表
            $params = array();
            $params['doctor_id'] = $user_doctor['doctor_id'];

            $data = array();
            $data['qr_code'] = $qr_code;
            UserDoctor::editUserDoctor($params,$data);
        }

        $result = array();
        $result['user_name'] = $user_doctor['user_name'];
        $result['doctor_title'] = DoctorTitleCode::getMessage($user_doctor['doctor_title']);
        $result['avatar'] = addAliyunOssWebsite($user_doctor['avatar']);
        $result['department_custom_name'] = $user_doctor['department_custom_name'];
        $result['hospital_name'] = $hospital['hospital_name'];
        $result['qr_code_url'] = addAliyunOssWebsite($user_doctor['qr_code'] ?? $qr_code);

        return success($result);
    }

    /**
     * 获取医生问诊消息列表
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getDoctorMessageList(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $message_inquiry_type = $this->request->input('message_inquiry_type');

        $redis_key = "recentContact" . $user_info['client_user_id'] . $message_inquiry_type;

        $redis = $this->container->get(Redis::class);
        $result = $redis->hVals($redis_key);
        if (empty($result)){
            return success();
        }

        foreach ($result as &$item){
            $item = json_decode($item,true);
        }

        // 获取 message_send_time 和 message_seq 两个字段的值，分别存储在不同的数组中
        foreach ($result as $key => $row) {
            $messageSendTime[$key]  = $row['message_send_time'];
            $messageSeq[$key] = $row['message_seq'];
        }

        // 通过 array_multisort 函数对两个字段进行排序
        // 优先按照 message_send_time 排序，如果 message_send_time 相同，则按照 message_seq 排序
        array_multisort($messageSendTime, SORT_DESC, $messageSeq, SORT_DESC, $result);

        return success($result);
    }

    /**
     * 获取医生问诊消息用户属性
     * @return array
     */
    public function getDoctorMessageAttrList(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_inquiry_ids = $this->request->input('order_inquiry_ids');
        if (empty($order_inquiry_ids)){
            return fail();
        }

        $order_inquiry_ids = explode(',',$order_inquiry_ids);

        $fields = [
            'order_inquiry_id',
            'patient_name',
            'patient_sex',
            'patient_age',
            'inquiry_status',
        ];

        $params =array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $order_inquiry = OrderInquiry::getInList($params,$order_inquiry_ids,$fields);
        if (empty($order_inquiry)){
            return success();
        }

        $result = [];
        foreach ($order_inquiry as $value){
            $result[] = $value;
        }

        return success($result);
    }

    /**
     * 新增医生接诊
     * @return array
     * @throws GuzzleException
     */
    public function addDoctorInquiry(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_inquiry_id = $this->request->route('order_inquiry_id');

        // 获取问诊订单数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['order_inquiry_id'] = $order_inquiry_id;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail(HttpEnumCode::HTTP_ERROR, "接诊失败");
        }

        if ($order_inquiry['inquiry_status'] != 3) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            return fail(HttpEnumCode::HTTP_ERROR, "接诊失败");
        }

        // 订单退款状态
        if (!in_array($order_inquiry['inquiry_refund_status'],[0,4,5])){
            // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常）
            return fail(HttpEnumCode::HTTP_ERROR, "订单正在退款，无法接诊");
        }

        // 订单支付状态
        if ($order_inquiry['inquiry_pay_status'] != 2){
            return fail(HttpEnumCode::HTTP_ERROR, "订单未支付，无法接诊");
        }

        Db::beginTransaction();

        try {
            $data = array();
            $data['inquiry_status'] = 4;
            $data['reception_time'] = date('Y-m-d H:i:s',time());

            $params = array();
            $params['order_inquiry_id'] = $order_inquiry_id;
            OrderInquiry::edit($params,$data);

            // 发送问诊消息
            $ImService = new ImService();

            // 发送消息
            $cloud_custom_data = array();
            $cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
            $cloud_custom_data['is_system'] = 1;
            $cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
            $cloud_custom_data['message_rounds'] = 0;
            $cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
            $cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
            $cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];

            // 消息内容
            $message_content_data = array();
            $message_content_data['message_type'] = 1;
            $message_content_data['title'] = "";
            $message_content_data['desc'] = "";

            if ($order_inquiry['inquiry_type'] == 1){
                $message_content_data['title'] = "--问诊已开始，本次问诊可持续24小时--";
                $message_content_data['desc'] = "医生已接诊，您可继续补充问诊内容，如目前症状、患病时长、检查及用药情况、需要的帮助等，线上咨询不能代表面诊，医生的回复仅为建议。";
            } elseif ($order_inquiry['inquiry_type'] == 2){
                $message_content_data['title'] = "--问诊已开始，本次问诊可持续60分钟--";
                $message_content_data['desc'] = "医生已接诊，您可继续补充问诊内容，如目前症状、患病时长、检查及用药情况、需要的帮助等，线上咨询不能代表面诊，医生的回复仅为建议。";
            } elseif ($order_inquiry['inquiry_type'] == 3){
                $message_content_data['title'] = "--问诊已开始，本次问诊可持续24小时--";
                $message_content_data['desc'] = "医生已接诊，您可一次描述需要问诊的内容，以免浪费问诊次数，如目前症状、患病时长、检查及用药情况、需要的帮助等，线上咨询不能代表面诊，医生的回复仅为建议。";
            } elseif ($order_inquiry['inquiry_type'] == 4){
                $message_content_data['title'] = "--问诊已开始，本次问诊可持续30分钟--";
                $message_content_data['desc'] = "医生已接诊，您可继续补充问诊内容，如目前症状、患病时长、检查及用药情况、需要的帮助等，线上咨询不能代表面诊，医生的回复仅为建议。";
            }

            $message_content = [
                'Data' => json_encode($message_content_data,JSON_UNESCAPED_UNICODE),
            ];

            $ImService->sendMessage($user_info['user_id'], $order_inquiry['user_id'], $message_content, "TIMCustomElem", $cloud_custom_data);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }

        return success();
    }

    /**
     * 结束问诊
     * @return array
     * @throws GuzzleException
     */
    public function putDoctorFinishInquiry(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        $order_inquiry_id = $this->request->route('order_inquiry_id');

        // 获取问诊订单数据
        $params = array();
        $params['doctor_id'] = $user_info['client_user_id'];
        $params['order_inquiry_id'] = $order_inquiry_id;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail(HttpEnumCode::HTTP_ERROR, "非法订单");
        }

        if ($order_inquiry['inquiry_status'] != 4) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            return fail(HttpEnumCode::HTTP_ERROR, "操作失败");
        }

        // 订单退款状态
        if (!in_array($order_inquiry['inquiry_refund_status'],[0,4,5])){
            // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常）
            return fail(HttpEnumCode::HTTP_ERROR, "订单正在退款，无法结束");
        }

        // 订单支付状态
        if ($order_inquiry['inquiry_pay_status'] != 2){
            return fail(HttpEnumCode::HTTP_ERROR, "订单未支付，无法结束");
        }

        Db::beginTransaction();

        try {
            $data = array();
            $data['inquiry_status'] = 5;// 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            $data['complete_time'] = date('Y-m-d H:i:s',time());// 订单完成时间（问诊完成时间）

            $params = array();
            $params['order_inquiry_id'] = $order_inquiry_id;
            OrderInquiry::edit($params,$data);

            // 发送问诊消息
            $ImService = new ImService();

            // 发送消息
            $cloud_custom_data = array();
            $cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
            $cloud_custom_data['is_system'] = 1;
            $cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
            $cloud_custom_data['message_rounds'] = 0;
            $cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
            $cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
            $cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];

            // 消息内容
            $message_content_data = array();
            $message_content_data['message_type'] = 1;
            $message_content_data['title'] = "问诊已结束";
            $message_content_data['desc'] = "线上咨询不能代替问诊，医生的回复仅为建议。";
            $message_content = [
                'Data' => json_encode($message_content_data,JSON_UNESCAPED_UNICODE),
            ];

            $ImService->sendMessage($user_info['user_id'], $order_inquiry['user_id'], $message_content, "TIMCustomElem", $cloud_custom_data);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
        }

        return success();
    }

    /**
     * 检测医生身份认证
     * @param object|array $user_doctor 医生表数据
     * @param bool $is_iden_auth 是否检测身份认证
     * @param bool $is_idcard 是否检测实名认证
     * @param bool $is_multi_point 是否检测多点执业认证
     * @return bool|string string：错误信息 bool：通过
     */
    public function checkDoctorAuth(object|array $user_doctor, bool $is_iden_auth = true, bool $is_idcard = true, bool $is_multi_point = true): bool|string
    {
        if (empty($user_doctor)) {
            throw new BusinessException();
        }

        if ($is_iden_auth) {
            if ($user_doctor['iden_auth_status'] != 1) {
                return "请先完成身份认证";
            }
        }

        if ($is_idcard) {
            if ($user_doctor['idcard_status'] != 1) {
                return "请先完成实名认证";
            }
        }

        if ($is_multi_point) {
            if ($user_doctor['multi_point_status'] != 1) {
                return "请先完成多点执业认证";
            }
        }

        return true;
    }

    /**
     * 检测是否存在对应问诊的在线医生
     * @param int|string $inquiry_type 订单类型（1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
     * @return bool
     */
    public function checkDoctorOnline(int|string $inquiry_type): bool
    {
        $params = array();
        $params['status'] = 1; // 状态
        $params['idcard_status'] = 1; // 实名认证状态
        $params['iden_auth_status'] = 1;// 身份认证状态

        if ($inquiry_type == 4) {
            // 问诊购药
            $params['multi_point_status'] = 1;// 医生多点执业认证状态（0:未认证 1:认证通过 2:审核中 3:认证失败）
        }

        $params['is_online'] = 1;// 是否在线（0:不在线 1:在线）

        switch ($inquiry_type) {
            case 1:
                // 专家
                $params['is_img_expert_reception'] = 1;// 是否参加专家图文接诊（0:否 1:是）
                break;
            case 2:
                // 快速
                $params['is_img_quick_reception'] = 1;// 是否参加快速图文接诊（0:否 1:是）
                break;
            case 3:
                // 公益
                $params['is_img_welfare_reception'] = 1;// 是否参加公益图文问诊（0:否 1:是）
                break;

            default:
                throw new BusinessException();
                break;
        }

        return UserDoctor::getExists($params);
    }

    /**
     * 获取当前时间N分钟前接诊中的医生
     * @param string|int $minute 分钟
     * @param int|string $inquiry_type 订单类型（1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
     * @param array $not_doctor_ids 不可选择的医生id数组
     * @return array
     */
    public function getBeforeCurrentTimeDoctor(string|int $minute, int|string $inquiry_type,array $not_doctor_ids = []): array
    {
        // 获取当前时间n分钟前时间
        $date = date('Y-m-d H:i:s', time() - $minute * 60);

        $params = array();
        $params[] = ['inquiry_type', '=', $inquiry_type]; // 订单类型（1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
        $params[] = ['inquiry_mode', '=', 1];
        $params[] = ['reception_time', '>', $date];

        $inquiry_status_params = array();
        $inquiry_status_params = [4, 5];// 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
        $order_inquirys = OrderInquiry::getInquiryStatusWithDoctorNotInList($params, $inquiry_status_params,$not_doctor_ids);
        if (empty($order_inquirys)) {
            return [];
        }

        $result = [];
        foreach ($order_inquirys as $item){
            $result[] = $item['UserDoctor'];
        }

        return $result;
    }

    /**
     * 获取快速、购药问诊可分配医生
     * @param string $inquiry_type
     * @param string $patient_id
     * @return string
     */
    public function getInquiryAssignDoctor(string $inquiry_type,string $patient_id): string
    {
        // 获取问诊配置
        $params = array();
        $params['inquiry_type'] = $inquiry_type;
        $params['inquiry_mode'] = 1;
        $system_inquiry_config = SystemInquiryConfig::getOne($params);
        if (empty($system_inquiry_config)){
            return "";
        }

        // 获取系统工作时间
        $params = array();
        $params['system_inquiry_config_id'] = $system_inquiry_config['system_inquiry_config_id'];
        $system_inquiry_time = SystemInquiryTime::getList($params);
        if (empty($system_inquiry_time)){
            return "";
        }

        // 检测当前是否坐班时间
        $is_time_pass = false; // 非坐班时间

        foreach ($system_inquiry_time as $item){
            $now_time = date('H',time()) . date('i',time());
            if ($item['start_time'] < $now_time && $item['end_time'] > $now_time){
                // 符合当前时间区间
                $is_time_pass = true;
            }
        }

        // 不可选择的医生id数组
        $not_doctor_ids = [];

        while (true){
            // 系统坐班时间
            if ($is_time_pass){
                // 获取坐班时间包含当前时间的深度合作医生
                $doctor_id = $this->getNowTimePlatDeepCooperationDoctorId($inquiry_type,time(),$not_doctor_ids);
                if (!empty($doctor_id)){
                    // 检测当前医生是否和患者存在未完成问诊订单
                    $InquiryService = new InquiryService();
                    $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$doctor_id);
                    if (!empty($order_inquiry)){
                        // 存在未完成问诊订单，记录该医生id，重新分配
                        $not_doctor_ids[] = $order_inquiry['doctor_id'];
                        continue;
                    }

                    // 不存在未完成的问诊订单
                    break;
                }
            }

            // 获取深度合作的在线医生
            $params = array();
            $params['status'] = 1;
            $params['idcard_status'] = 1;
            $params['iden_auth_status'] = 1;
            $params['is_bind_bank'] = 1;
            $params['is_online'] = 1;
            if ($inquiry_type == 2){
                // 快速问诊
                $params['is_img_quick_reception'] = 1;
            }elseif ($inquiry_type == 4){
                // 问诊购药
                $params['multi_point_status'] = 1;
            }
            $params['is_platform_deep_cooperation'] = 1;

            $user_doctor = UserDoctor::getUserDoctorNotInOne($params,$not_doctor_ids);
            if (!empty($user_doctor)){
                // 检测当前医生是否和患者存在未完成问诊订单
                $InquiryService = new InquiryService();
                $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$user_doctor['doctor_id']);
                if (!empty($order_inquiry)){
                    // 存在未完成问诊订单，记录该医生id，重新分配
                    $not_doctor_ids[] = $order_inquiry['doctor_id'];
                    continue;
                }

                // 不存在未完成的问诊订单
                $doctor_id = $user_doctor['doctor_id'];
                break;
            }

            // 获取在线的自由注册医生
            $params = array();
            $params['status'] = 1;
            $params['idcard_status'] = 1;
            $params['iden_auth_status'] = 1;
            $params['is_bind_bank'] = 1;
            $params['is_online'] = 1;
            if ($inquiry_type == 2){
                // 快速问诊
                $params['is_img_quick_reception'] = 1;
            }elseif ($inquiry_type == 4){
                // 问诊购药
                $params['multi_point_status'] = 1;
            }
            $user_doctor = UserDoctor::getUserDoctorNotInOne($params,$not_doctor_ids);
            if (!empty($user_doctor)){
                // 检测当前医生是否和患者存在未完成问诊订单
                $InquiryService = new InquiryService();
                $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$user_doctor['doctor_id']);
                if (!empty($order_inquiry)){
                    // 存在未完成问诊订单，记录该医生id，重新分配
                    $not_doctor_ids[] = $order_inquiry['doctor_id'];
                    continue;
                }

                // 获取医生每日最大接诊数量
                $UserDoctorService = new UserDoctorService();
                $max_work_num_day = $UserDoctorService->getDoctorInquiryDayMaxNum($user_doctor['doctor_id'],$inquiry_type,1);

                // 获取医生未接诊订单数量(包含未接诊、未支付、已接诊)
                $order_inquiry_count = $UserDoctorService->getDoctorUnInquiryOrderNum($user_doctor['doctor_id'],$inquiry_type,1);

                // 计算剩余未接诊数量 = 最大数量-
                $access_inquiry_num = $max_work_num_day - $order_inquiry_count;

                if ($access_inquiry_num <= 0){
                    // 分配的医生无问诊次数，重新分配
                    $not_doctor_ids[] = $user_doctor['doctor_id'];
                    continue;
                }

                // 未超出最大接诊量
                $doctor_id = $user_doctor['doctor_id'];
                break;
            }

            // 检测当前时间5分钟后，坐班时间包含某时间的平台深度合作医生
            $doctor_id = $this->getNowTimePlatDeepCooperationDoctorId($inquiry_type,strtotime ("+5 minute"),$not_doctor_ids);
            if (!empty($doctor_id)){
                // 检测当前医生是否和患者存在未完成问诊订单
                $InquiryService = new InquiryService();
                $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$doctor_id);
                if (!empty($order_inquiry)){
                    // 存在未完成问诊订单，记录该医生id，重新分配
                    $not_doctor_ids[] = $order_inquiry['doctor_id'];
                    continue;
                }

                // 不存在未完成的问诊订单
                break;
            }

            // 当前时间10分钟内接诊中医生
            $doctors = $this->getBeforeCurrentTimeDoctor(10,$inquiry_type,$not_doctor_ids);
            if (!empty($doctors)){
                foreach ($doctors as $item){
                    // 自由注册医生检测接诊数量
                    if ($item['is_platform_deep_cooperation'] == 0){
                        // 获取医生每日最大接诊数量
                        $UserDoctorService = new UserDoctorService();
                        $max_work_num_day = $UserDoctorService->getDoctorInquiryDayMaxNum($item['doctor_id'],$inquiry_type,1);

                        // 获取医生未接诊订单数量(包含未接诊、未支付、已接诊)
                        $order_inquiry_count = $UserDoctorService->getDoctorUnInquiryOrderNum($item['doctor_id'],$inquiry_type,1);

                        // 计算剩余未接诊数量 = 最大数量-
                        $access_inquiry_num = $max_work_num_day - $order_inquiry_count;

                        if ($access_inquiry_num <= 0){
                            // 分配的医生无问诊次数，重新分配
                            $not_doctor_ids[] = $item['doctor_id'];
                            continue;
                        }
                    }

                    // 检测当前医生是否和患者存在未完成问诊订单
                    $InquiryService = new InquiryService();
                    $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$item['doctor_id']);
                    if (!empty($order_inquiry)){
                        // 存在未完成问诊订单，记录该医生id，重新分配
                        $not_doctor_ids[] = $order_inquiry['doctor_id'];
                        continue;
                    }

                    $doctor_id = $item['doctor_id'];
                    break 2;
                }
            }

            // 当前时间10分钟内接诊中医生
            $doctors = $this->getBeforeCurrentTimeDoctor(30,$inquiry_type,$not_doctor_ids);
            if (!empty($doctors)){
                foreach ($doctors as $item){
                    // 自由注册医生检测接诊数量
                    if ($item['is_platform_deep_cooperation'] == 0){
                        // 获取医生每日最大接诊数量
                        $UserDoctorService = new UserDoctorService();
                        $max_work_num_day = $UserDoctorService->getDoctorInquiryDayMaxNum($item['doctor_id'],$inquiry_type,1);

                        // 获取医生未接诊订单数量(包含未接诊、未支付、已接诊)
                        $order_inquiry_count = $UserDoctorService->getDoctorUnInquiryOrderNum($item['doctor_id'],$inquiry_type,1);

                        // 计算剩余未接诊数量 = 最大数量-
                        $access_inquiry_num = $max_work_num_day - $order_inquiry_count;

                        if ($access_inquiry_num <= 0){
                            // 分配的医生无问诊次数，重新分配
                            $not_doctor_ids[] = $item['doctor_id'];
                            continue;
                        }
                    }

                    // 检测当前医生是否和患者存在未完成问诊订单
                    $InquiryService = new InquiryService();
                    $order_inquiry = $InquiryService->checkPatientDoctorProgressInquiry($patient_id,$item['doctor_id']);
                    if (!empty($order_inquiry)){
                        // 存在未完成问诊订单，记录该医生id，重新分配
                        $not_doctor_ids[] = $order_inquiry['doctor_id'];
                        continue;
                    }

                    $doctor_id = $item['doctor_id'];
                    break 2;
                }
            }

            // 医生id归为空
            $doctor_id = "";
            break;
        }

        return $doctor_id;
    }


    /**
     * 获取坐班时间包含某时间的平台深度合作医生
     * @param string $inquiry_type
     * @param string $time 时间戳
     * @param array $not_doctor_ids 不可选择的医生id数组
     * @return string
     */
    public function getNowTimePlatDeepCooperationDoctorId(string $inquiry_type,string $time,array $not_doctor_ids = []): string
    {
        $params = array();
        $params[] = ['inquiry_type','=',$inquiry_type];
        $params[] = ['inquiry_mode','=',1];
        $params[] = ['start_time','<',date('H',$time) . date('i',$time)];
        $params[] = ['end_time','>',date('H',$time) . date('i',$time)];

        $user_doctor_params = array();
        $user_doctor_params['is_platform_deep_cooperation'] = 1;
        if ($inquiry_type == 2){
            // 快速问诊
            $user_doctor_params['is_img_quick_reception'] = 1;
        }elseif ($inquiry_type == 4){
            // 问诊购药
            $user_doctor_params['multi_point_status'] = 1;
        }
        $doctor_inquiry_times = DoctorInquiryTime::getWithDoctorNotInList($params,$user_doctor_params,$not_doctor_ids);
        if (!empty($doctor_inquiry_times)){
            foreach ($doctor_inquiry_times as $item){
                // 检测是否存在日期
                if (!empty($item['inquiry_date'])){
                    // 获取当前日期
                    $now_day = date('Y-m-d',time());
                    if ($item['inquiry_date'] == $now_day){
                        return $item['doctor_id'];
                    }else{
                        continue;
                    }
                }else{
                    return $item['doctor_id'];
                }
            }
        }

        return "";
    }

    /**
     * 获取医生每日最大接诊数量
     * @param string $doctor_id
     * @param string|int $inquiry_type
     * @param string|int $inquiry_mode
     * @return int
     */
    public function getDoctorInquiryDayMaxNum(string $doctor_id,string|int $inquiry_type,string|int $inquiry_mode): int
    {
        $max_work_num_day = 0;
        if ($inquiry_type == 4){
            // 问诊购药由系统统一配置
            $params = array();
            $params['inquiry_type'] = $inquiry_type;
            $params['inquiry_mode'] = $inquiry_mode;
            $system_inquiry_config = SystemInquiryConfig::getOne($params);
            if (!empty($system_inquiry_config)){
                $max_work_num_day = $system_inquiry_config['max_work_num_day'];
            }
        }else{
            $params = array();
            $params['doctor_id'] = $doctor_id;
            $params['inquiry_type'] = $inquiry_type;
            $params['inquiry_mode'] = $inquiry_mode;
            $doctor_inquiry_config = DoctorInquiryConfig::getOne($params);
            if (!empty($doctor_inquiry_config)){
                $max_work_num_day = $doctor_inquiry_config['work_num_day'];
            }
        }

        return $max_work_num_day;
    }

    /**
     * 获取医生未接诊订单数量(包含未接诊、未支付、已接诊)
     * @param string $doctor_id
     * @param string|int $inquiry_type
     * @param string|int $inquiry_mode
     * @return int
     */
    public function getDoctorUnInquiryOrderNum(string $doctor_id,string|int $inquiry_type,string|int $inquiry_mode): int
    {
        $params = array();
        $params['doctor_id'] = $doctor_id;
        $params['inquiry_type'] = $inquiry_type;
        $params['inquiry_mode'] = $inquiry_mode;
        $params['inquiry_refund_status'] = 0;

        $inquiry_status_params = [1,3,4];
        return OrderInquiry::getInquiryStatusCount($params,$inquiry_status_params);
    }
}