request->getAttribute("userInfo") ?? []; $date = $this->request->input('date'); // 获取医生账户余额 $balance_account = $this->getDoctorBalanceAccount($user_info['client_user_id']); // 获取医生月度余额 $amount_total_month = $this->getDoctorMonthAmountTotal($user_info['client_user_id'], $date); // 获取医生月度已提现金额-审核通过时间为准 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $doctor_withdrawal = DoctorWithdrawal::getOne($params); if (empty($doctor_withdrawal)) { $withdrawal_amount_month = 0; } else { $withdrawal_amount_month = $doctor_withdrawal['actual_withdrawal_amount']; } // 获取医生每日账单数据 $bill = []; $fields = [ 'total_amount', 'month', 'day', ]; $params = array(); $params['doctor_id'] = $user_info['client_user_id']; $params['year'] = date('Y', strtotime($date)); $params['month'] = date('m', strtotime($date)); $doctor_account_days = DoctorAccountDay::getList($params, $fields); if (!empty($doctor_account_days)) { foreach ($doctor_account_days as $doctor_account_day) { $data = array(); $data['total_amount'] = ceil($doctor_account_day['total_amount'] * 100) / 100; $data['month'] = $doctor_account_day['month']; $data['day'] = $doctor_account_day['day']; $bill[] = $data; } unset($doctor_account_days); } $result = array(); $result['balance_account'] = ceil($balance_account * 0.75 * 100) / 100;; // 账户余额 $result['amount_total_month'] = ceil($amount_total_month * 0.75 * 100) / 100; // 月余额 $result['withdrawal_amount_month'] = ceil($withdrawal_amount_month * 0.75 * 100) / 100; // 月已提现金额 $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); // 获取当天开始时间 $start_date = date('Y-m-d 00:00:00', strtotime($date)); // 获取当天结束时间 $end_date = date('Y-m-d 23:59:59', strtotime($date)); $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', ]; $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:退款关闭) $order_inquiry = OrderInquiry:: getDoctorDateOrderInquiryPage($params, $reception_time, $fields,$page,$per_page); if (!empty($order_inquiry['data'])) { foreach ($order_inquiry['data'] as &$item) { $item['amount_total'] = ceil($item['total_amount'] * 0.75 * 100) / 100; } } 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, "非法医生"); } // 检测医生身份认证 $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'] = $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']; $balance_account = 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)){ $balance_account = array_sum(array_column($order_inquiry->toArray(),'amount_total')); } $order_inquiry_id_array = $in_params; }else{ $InquiryService = new InquiryService(); $order_inquiry = $InquiryService->getDoctorCanWithdrawalInquiryOrder($user_info['client_user_id']); if (!empty($order_inquiry)){ $balance_account = array_sum(array_column($order_inquiry,'amount_total')); $order_inquiry_id_array = array_column($order_inquiry,'order_inquiry_id'); } } if ($balance_account > 0){ $balance_account = floor($balance_account * 0.75 * 100) / 100; } // 计算医生个人所得税 $income_tax = $this->computeIndividualIncomeTax($balance_account); $withdrawal_amount = floor(($balance_account - $income_tax) * 100) / 100; $income_tax = floor($income_tax * 100) / 100; $result = array(); $result['bank'] = $bank;//银行数据 $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); // 获取医生当日接诊订单金额 $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_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:退款关闭) $order_inquiry = OrderInquiry:: getDoctorOrderInquiryPage($params, $fields,$page,$per_page); if (!empty($order_inquiry['data'])) { foreach ($order_inquiry['data'] as &$item) { $item['expected_amount_total'] = ceil($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(); } $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 += $order_inquiry['amount_total']; } // 医生分成金额 if ($amount_total > 0){ $amount_total = floor($amount_total * 0.75 * 100) / 100; } // 计算医生个人所得税 $income_tax = $this->computeIndividualIncomeTax($amount_total); // 可提现金额 $withdrawal_amount = floor(($amount_total - $income_tax) * 100) / 100; $income_tax = floor($income_tax * 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['bank_id'] = $doctor_bank_card['bank_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);; $data['applied_withdrawal_amount'] = $withdrawal_amount + $income_tax; // 提现金额 $data['actual_withdrawal_amount'] = $withdrawal_amount; // 实际提现金额 $data['income_tax'] = $income_tax; // 提现所得税金额 $data['examine_status'] = 1; // 审核状态(1:审核中 2:审核通过 3:审核未通过) $doctor_withdrawal = DoctorWithdrawal::addDoctorWithdrawal($data); if (empty($doctor_withdrawal)){ 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',$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|int $income * @return float|int */ protected function computeIndividualIncomeTax(string|int $income): float|int { if ($income <= 800) { return 0; } if ($income <= 4000) { $income = $income - 800; } // 实际纳税金额 $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; } }