request->getAttribute("userInfo") ?? []; $year = $this->request->input('date'); $date = date('Y-m-d',time()); // 获取医生数据 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $user_doctor = UserDoctor::getOne($params); if (empty($user_doctor)){ return fail(); } $inquiryService = new InquiryService(); if ($user_doctor['is_platform_deep_cooperation'] == 0){ // 获取医生当日接诊的订单金额 $doctor_today_inquiry_total = $inquiryService->getDoctorDayAmountTotal($user_info['client_user_id'],$date); // 获取医生当日已完成未结束的订单金额 $doctor_day_completed_amount_total = $inquiryService->getDoctorDayCompletedAmountTotal($user_info['client_user_id'],$date); }else{ // 获取医生当日接诊的订单金额-坐班医生 $doctor_today_inquiry_total = $inquiryService->getCooperationDoctorDayAmountTotal($user_info['client_user_id'],$date); // 获取医生当日已完成未结束的订单金额-坐班医生 $doctor_day_completed_amount_total = $inquiryService->getCooperationDoctorCompletedAmountTotal($user_info['client_user_id'],$date); } // 获取医生账户余额 $balance_account = $this->getDoctorBalanceAccount($user_info['client_user_id']); // 获取医生每月账单数据 $bill = []; $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $params['year'] = $year; $doctor_account_days = DoctorAccountDay::getDoctorMonth($params); if (!empty($doctor_account_days)) { foreach ($doctor_account_days as $doctor_account_day) { $data = array(); $data['total_amount'] = bcmul((string)$doctor_account_day['total_amount'],1,2); $data['month'] = $doctor_account_day['month']; $bill[] = $data; } unset($doctor_account_days); } $result = array(); $result['doctor_today_inquiry_total'] = bcmul((string)$doctor_today_inquiry_total,"0.75",2); // 今日接诊收入 $result['doctor_day_completed_amount_total'] = bcmul((string)$doctor_day_completed_amount_total ,"0.75",2); // 今日已完成收入 $result['balance_account'] = bcmul((string)$balance_account ,"1",2); // 账户余额 $result['bill'] = $bill; // 账单 return success($result); } /** * 获取我的账户月账单明细数据 * @return array */ public function getDoctorAccountInfo(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; $date = $this->request->input('date'); $page = $this->request->input('page', 1); $per_page = $this->request->input('per_page', 10); // 获取医生数据 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $user_doctor = UserDoctor::getOne($params); if (empty($user_doctor)){ return fail(); } // 获取当月开始时间 $start_date = date('Y-m-01 00:00:00', strtotime($date)); // 获取当月结束时间 // 获取给定月份的下一个月的第一天,然后减去一天得到当月的最后一天 $end_date = date("Y-m-d 23:59:59", strtotime("+1 month", strtotime($start_date)) - 1); $reception_time = [$start_date, $end_date]; // 获取医生当日接诊订单金额 $fields = [ 'order_inquiry_id', 'inquiry_type', 'inquiry_mode', 'inquiry_status', 'inquiry_refund_status', 'inquiry_no', 'amount_total', 'payment_amount_total', 'reception_time', 'finish_time', 'patient_name', 'patient_sex', 'patient_age', 'cancel_reason', 'cancel_remarks', 'created_at', ]; $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $inquiry_status_params = [4,5,6,7]; // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) if ($user_doctor['is_platform_deep_cooperation'] == 0){ $order_inquiry = OrderInquiry:: getDoctorCreatedDateOrderInquiryPage($params, $reception_time, $inquiry_status_params,[],$fields,$page,$per_page); }else{ $order_inquiry = OrderInquiry:: getDoctorCreatedDateOrderInquiryPage($params, $reception_time, $inquiry_status_params,[2,4],$fields,$page,$per_page); } if (!empty($order_inquiry['data'])) { foreach ($order_inquiry['data'] as &$item) { $item['estimate_income'] = bcmul((string)$item['amount_total'],"0.75",2); // 入账状态 if ($item['inquiry_status'] == 4 || $item['inquiry_status'] == 5){ $item['entry_status'] = 1;// 入账中 }elseif ($item['inquiry_status'] == 6){ $item['entry_status'] = 2;// 入账成功 }elseif ($item['inquiry_status'] == 7){ $item['entry_status'] = 3;// 入账失败 if (!empty($item['cancel_reason'])){ $item['cancel_reason'] = inquiryCancelReasonToPushString($item['cancel_reason']); } }else{ $item['entry_status'] = 0;// 未知 } } } return success($order_inquiry); } /** * 获取提现数据 * @return array */ public function getDoctorWithdrawalInfo(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; $order_inquiry_ids = $this->request->input('order_inquiry_ids'); // 获取医生信息 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $fields = [ 'doctor_id', 'user_name', 'iden_auth_status', 'idcard_status', 'multi_point_status', 'avatar', 'is_bind_bank', ]; $user_doctor = UserDoctor::getOne($params, $fields); if (empty($user_doctor)) { return fail(HttpEnumCode::HTTP_ERROR, "非法医生"); } $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $user_doctor_info = UserDoctorInfo::getOne($params); if (empty($user_doctor_info)) { return fail(HttpEnumCode::HTTP_ERROR, "非法医生"); } // 检测医生身份认证 $UserDoctorService = new UserDoctorService(); $res = $UserDoctorService->checkDoctorAuth($user_doctor); if ($res !== true) { return fail(HttpEnumCode::HTTP_ERROR, $res); } if ($user_doctor['is_bind_bank'] != 1) { return fail(HttpEnumCode::HTTP_ERROR, "未绑定结算银行卡"); } // 获取医生结算银行卡 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $doctor_bank_card = DoctorBankCard::getWithBankOne($params); if (empty($doctor_bank_card)) { return success(); } $bank = array(); $bank['bank_card_id'] = $doctor_bank_card['bank_card_id']; $bank['bank_icon_path'] = addAliyunOssWebsite($doctor_bank_card['BasicBank']['bank_icon_path']); $bank['bank_name'] = $doctor_bank_card['BasicBank']['bank_name']; $bank['bank_card_code_mask'] = $doctor_bank_card['bank_card_code_mask']; $bank['bank_card_name'] = $user_doctor_info['card_name']; $bank['bank_card_name_mask'] = $user_doctor_info['card_name_mask']; $amount_total = 0; $order_inquiry_id_array = []; // 获取医生账户余额 if (!empty($order_inquiry_ids)){ $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $params['inquiry_status'] = 6; // inquiry_status:问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) $params['inquiry_refund_status'] = 0; // inquiry_refund_status:问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) $in_params = explode(',',$order_inquiry_ids); $order_inquiry = OrderInquiry::getInList($params,$in_params); if (!empty($order_inquiry)){ foreach ($order_inquiry as $value){ $amount_total = bcadd((string)$amount_total,(string)$value["amount_total"],2); } } $order_inquiry_id_array = $in_params; }else{ $InquiryService = new InquiryService(); if ($user_doctor['is_platform_deep_cooperation'] == 0){ $order_inquiry = $InquiryService->getDoctorCanWithdrawalInquiryOrder($user_info['client_user_id']); }else{ $order_inquiry = $InquiryService->getCooperationDoctorCanWithdrawalInquiryOrder($user_info['client_user_id']); } if (!empty($order_inquiry)){ foreach ($order_inquiry as $value){ $amount_total = bcadd((string)$amount_total,(string)$value["amount_total"],2); } $order_inquiry_id_array = array_column($order_inquiry,'order_inquiry_id'); } } $amount_total = bcmul((string)$amount_total,"0.75",2); // 计算医生个人所得税 $income_tax = $this->computeIndividualIncomeTax($amount_total); $withdrawal_amount = bcsub($amount_total,$income_tax,2); $income_tax = bcmul($income_tax,1,2); $result = array(); $result['bank'] = $bank;//银行数据 $result['amount_total'] = $amount_total; // 账户余额 $result['withdrawal_amount'] = $withdrawal_amount; // 提现金额 $result['income_tax'] = $income_tax; // 个人所得税 $result['order_inquiry_ids'] = $order_inquiry_id_array; // 订单合集 return success($result); } /** * 获取可提现问诊订单列表 * @return array */ public function getDoctorWithdrawalOrderList(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; $page = $this->request->input('page', 1); $per_page = $this->request->input('per_page', 10); // 获取医生信息 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $user_doctor = UserDoctor::getOne($params); if (empty($user_doctor)) { return fail(); } // 获取医生当日接诊订单金额 $fields = [ 'order_inquiry_id', 'inquiry_type', 'inquiry_mode', 'inquiry_status', 'inquiry_refund_status', 'inquiry_no', 'amount_total', 'payment_amount_total', 'reception_time', 'finish_time', 'patient_name', 'patient_sex', 'patient_age', ]; $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $params['inquiry_refund_status'] = 0; // inquiry_refund_status:问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) $inquiry_status_params = [6]; // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) if ($user_doctor['is_platform_deep_cooperation'] == 0){ $order_inquiry = OrderInquiry:: getDoctorOrderInquiryPage($params,$inquiry_status_params, $fields,$page,$per_page); }else{ $inquiry_type_not_params = [2,4]; $order_inquiry = OrderInquiry:: getCooperationDoctorOrderInquiryPage($params,$inquiry_status_params,$inquiry_type_not_params, $fields,$page,$per_page); } if (!empty($order_inquiry['data'])) { foreach ($order_inquiry['data'] as &$item) { $item['expected_amount_total'] = floor($item['amount_total'] * 0.75 * 100) / 100; } } return success($order_inquiry); } /** * 获取医生提现记录列表 * @return array */ public function getDoctorWithdrawalRecordList(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; $year = $this->request->input('year'); $page = $this->request->input('page',1); $per_page = $this->request->input('per_page',10); // 获取当年开始时间 $start_date = $year.'-1-1 00:00:00'; // 获取当年结束时间 $end_date = $year.'-12-31 23:59:59'; $created_at_params = [$start_date, $end_date]; $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $doctor_withdrawal = DoctorWithdrawal::getDatePage($params,$created_at_params,['*'],$page,$per_page); if (empty($doctor_withdrawal['data'])){ return success(); } return success($doctor_withdrawal); } /** * 发起提现 * @return array */ public function addDoctorWithdrawal(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; $order_inquiry_id = $this->request->input('order_inquiry_id'); $withdrawal_amount_total = $this->request->input('withdrawal_amount_total'); $bank_card_id = $this->request->input('bank_card_id'); $order_inquiry_id = explode(',',$order_inquiry_id); if (empty($order_inquiry_id)){ return fail(); } $app_env = config('app_env'); if ($app_env != "dev"){ // 正式环境高于300元才可以提现 if ($withdrawal_amount_total < 300){ return fail(HttpEnumCode::HTTP_ERROR,"提现金额小于300元"); } } // 每月只能提现一次 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $start_time = date('Y-m-01',time()); $end_time = date('Y-m-t 24:00:00',time()); $created_at = [$start_time,$end_time]; $doctor_withdrawal = DoctorWithdrawal::getOneLatestTime($params,$created_at,['*'],); if (!empty($doctor_withdrawal)){ return fail("每月只允许提现一次"); } $amount_total = 0; foreach ($order_inquiry_id as $value){ $params = array(); $params['order_inquiry_id'] = $value; $params['doctor_id'] = $user_info['client_user_id']; $order_inquiry = OrderInquiry::getOne($params); if (empty($order_inquiry)){ return fail(HttpEnumCode::HTTP_ERROR,"存在不可提现订单"); } // 验证订单状态 if ($order_inquiry['inquiry_status'] != 6){ return fail(HttpEnumCode::HTTP_ERROR,"提现失败"); } // 验证订单提现状态 if ($order_inquiry['is_withdrawal'] != 0){ return fail(HttpEnumCode::HTTP_ERROR,"存在已提现订单"); } // 验证订单支付状态 if ($order_inquiry['inquiry_pay_status'] != 2){ return fail(HttpEnumCode::HTTP_ERROR,"存在未支付订单"); } // 计算订单总金额 $amount_total = bcadd($amount_total,$order_inquiry["amount_total"],2); } // 提现金额 $amount_total = $amount_total * 0.75; // 计算医生个人所得税 $income_tax = $this->computeIndividualIncomeTax($amount_total); // 实际提现金额 $withdrawal_amount = $amount_total - $income_tax; if ($withdrawal_amount > 0){ $withdrawal_amount = floor($withdrawal_amount * 100) / 100; } if ($withdrawal_amount_total != $withdrawal_amount){ return fail(HttpEnumCode::SERVER_ERROR,"金额不符合"); } // 检测提现银行卡 $params = array(); $params['bank_card_id'] = $bank_card_id; $doctor_bank_card = DoctorBankCard::getOne($params); if (empty($doctor_bank_card)){ return fail(HttpEnumCode::HTTP_ERROR,"银行卡错误"); } // 获取银行数据 $params = array(); $params['bank_id'] = $doctor_bank_card['bank_id']; $basic_bank = BasicBank::getOne($params); if (empty($basic_bank)){ return fail(HttpEnumCode::HTTP_ERROR,"银行卡错误"); } Db::beginTransaction(); try { // 新增医生提现表 $data = array(); $data['doctor_id'] = $user_info['client_user_id']; $data['account_name'] = $basic_bank['bank_name']; $data['bank_card_code'] = $doctor_bank_card['bank_card_code']; $data['bank_card_code_four'] = substr($doctor_bank_card['bank_card_code'], -4); if ($amount_total > 0){ $data['applied_withdrawal_amount'] = floor($amount_total * 100) / 100; // 提现金额 } $data['actual_withdrawal_amount'] = $withdrawal_amount; // 实际提现金额 if ($income_tax > 0){ $data['income_tax'] = floor($income_tax * 100) / 100; // 提现所得税金额 } $data['examine_status'] = 1; // 审核状态(1:审核中 2:审核通过 3:审核未通过) $doctor_withdrawal = DoctorWithdrawal::addDoctorWithdrawal($data); if (empty($doctor_withdrawal)){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR); } // 新增医生提现表-关联银行 $data = array(); $data['withdrawal_id'] = $doctor_withdrawal["withdrawal_id"]; $data['bank_id'] = $doctor_bank_card['bank_id']; $data['bank_card_code'] = $doctor_bank_card['bank_card_code']; $data['province_id'] = $doctor_bank_card['province_id']; $data['province'] = $doctor_bank_card['province']; $data['city_id'] = $doctor_bank_card['city_id']; $data['city'] = $doctor_bank_card['city']; $data['county_id'] = $doctor_bank_card['county_id']; $data['county'] = $doctor_bank_card['county']; $doctor_withdrawal_bank = DoctorWithdrawalBank::addDoctorWithdrawalBank($data); if (empty($doctor_withdrawal_bank)){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR); } foreach ($order_inquiry_id as $value){ // 新增医生提现-关联订单表 $data = array(); $data['withdrawal_id'] = $doctor_withdrawal['withdrawal_id']; $data['doctor_id'] = $user_info['client_user_id']; $data['order_inquiry_id'] = $value; $doctor_withdrawal_order = DoctorWithdrawalOrder::addDoctorWithdrawalOrder($data); if (empty($doctor_withdrawal_order)){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR); } // 修改问诊订单提现状态 $params = array(); $params['order_inquiry_id'] = $value; $data = array(); $data['is_withdrawal'] = 2; $data['withdrawal_time'] = date('Y-m-d H:i:s',time()); OrderInquiry::edit($params,$data); } // 账户表锁定 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; // 账户余额 DoctorAccount::dec($params,'balance_account',$amount_total); // 提现金额 DoctorAccount::inc($params,'applied_withdrawal_amount',$amount_total); // 实际提现金额 DoctorAccount::inc($params,'actual_withdrawal_amount',$withdrawal_amount); // 所得税金额 DoctorAccount::inc($params,'income_tax',$income_tax); Db::commit(); return success(); } catch (\Exception $e) { Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR,$e->getMessage()); } } /** * 获取医生账户余额 * @param string $doctor_id * @return float */ public function getDoctorBalanceAccount(string $doctor_id): float { $params = array(); $params['doctor_id'] = $doctor_id; $doctor_account = DoctorAccount::getOne($params); if (empty($doctor_account)) { $balance_account = 0; } else { $balance_account = $doctor_account['balance_account']; } return $balance_account; } /** * 获取某月医生账户已结束订单金额 * @param string $doctor_id 医生id * @param string $date 日期 Ymd形式 * @return float|int|mixed|string */ public function getDoctorMonthAmountTotal(string $doctor_id, string $date): mixed { $params = array(); $params['doctor_id'] = $doctor_id; $params['year'] = date('Y', strtotime($date)); $params['month'] = date('m', strtotime($date)); $total_amount = DoctorAccountDay::getDoctorSumTotalAmount($params); if (empty($total_amount)) { $total_amount = 0; } return $total_amount; } /** * 计算个人所得税 * @param string|float $income * @return float */ protected function computeIndividualIncomeTax(string|float $income): float { if ($income <= 800) { return 0; } if ($income <= 4000) { $income = $income - 800; } // 实际纳税金额 if ($income > 4000){ $income = $income * 0.8; } if ($income <= 20000) { $tax_rate = 0.2; // 税率 $quick_deduction = 0; // 速算扣除数 } elseif ($income <= 50000) { $tax_rate = 0.3;// 税率 $quick_deduction = 2000; // 速算扣除数 } else { $tax_rate = 0.4; $quick_deduction = 7000; // 速算扣除数 } $income_tax = $income * $tax_rate - $quick_deduction; return $income_tax; } }