first(); } public function findFinancialStat(int $channel_id) { return FinancialStat::where('distribution_channel_id', $channel_id)->first(); } public function findWithdrawCash(int $withdraw_cash_id) { return WithdrawCash::where('id', $withdraw_cash_id)->first(); } public function isWithdrawCashSuccess(string $status) { if (in_array($status, self::success_status)) { return true; } return false; } /** * 添加人工打款记录 */ private function addPayment(WithdrawCash $withdraw, string $trade_no, int $uid, string $remark) { $isCompanyName = $withdraw->is_company == 0 ? "对私" : "对公"; $remark = "[" . $isCompanyName . "]" . $remark; Payment::create( [ 'withdraw_cash_id' => $withdraw->id, 'amount' => (float) $withdraw->amount - (float) $withdraw->tallage, 'remark' => $remark, 'pay_time' => date('Y-m-d H:i:s'), 'pay_merchant_source' => "人工", 'trade_no' => $trade_no, 'status' => self::artifical_success, 'pay_merchant_source_msg' => '', 'is_company' => $withdraw->is_company, 'amount_person' => $uid, ] ); } /** * 查找操作账号 */ private function findManageUser(int $id) { return Manage::find($id); } /** * 更新提现信息状态 * @param WithdrawCash $withdraw * @param string $status * @param int $uid * @param string $serial_number * @param string $remark * @return WithdrawCash */ public function updateWithdrawCashStatus(WithdrawCash $withdraw, string $status, int $uid = 0, string $serial_number = '', string $remark = '') { if (in_array($withdraw->status, self::success_status)) { return; } $withdraw->status = $status; if ($uid) { $user = $this->findManageUser($uid); $withdraw->check_user_id = $uid; $withdraw->check_user_name = $user ? $user->nickname : ''; } if ($remark) { $withdraw->remark = $remark; } if ($serial_number) { if (!strpos($withdraw->serial_number, $serial_number)) { $serial_number = $withdraw->serial_number . "," . $serial_number; } $withdraw->serial_number = $serial_number; } $withdraw->save(); if (in_array($status, self::success_status)) { //成功提现 $financialStat = $this->findFinancialStat($withdraw->distribution_channel_id); //修改累计提现金额 $financialStat->accumulative_withdrawal_amount = (float) $financialStat->accumulative_withdrawal_amount + (float) $withdraw->amount; //修改提现中金额 $financialStat->withdraw_pending_amount = (float) $financialStat->withdraw_pending_amount - (float) $withdraw->amount; $financialStat->save(); } return $withdraw; } /** * 创建人工打款 * @param $userId * @param $withdrawCashId * @param $amount * @param $remark * @param $tradeNo * @param int $amount_person * @return bool */ public function makePersonMadePayment($userId, $withdrawCashId, $remark, $trade_no, $amount_person = 0) { try { DB::beginTransaction(); $withdraw = $this->findWithdrawCash($withdrawCashId); //插入人工打款记录 $this->addPayment($withdraw, $trade_no, $amount_person, $remark); //更新当然提现记录为 人工打款成功状态 $this->updateWithdrawCashStatus($withdraw, self::artifical_success, $userId, $trade_no, $remark); DB::commit(); } catch (Exception $e) { Log::error("人工打款失败日志" . $e->getTraceAsString()); DB::rollback(); return false; } return true; } /** * 对私打款改为对公打款 */ public function changePrivateToPublicPayment(int $uid, int $batch_payment_id, string $trade_no, string $account_name, string $card_number, string $account_bank) { $withdraws = WithdrawCash::where('batch_payment_id', $batch_payment_id)->get(); DB::beginTransaction(); foreach ($withdraws as $withdraw) { $withdraw->account_name = $account_name; $withdraw->bank_account = $card_number; $withdraw->account_bank = $account_bank; $withdraw->batch_payment_id = 0; $withdraw->status = '人工待打款'; $withdraw->is_company = 1; $withdraw->is_batch_operate = 0; $withdraw->save(); if (!$this->makePersonMadePayment($uid, $withdraw->id, "[对私转对公]", $trade_no)) { DB::rollback(); return; } } BatchPayments::where('id', $batch_payment_id)->delete(); DB::commit(); } /** * 更新合并打款对应的提现状态 */ private function updateBatchPaymentWithdrawCashStatus(int $batch_payment_id, string $status, int $uid = 0, string $serial_number = '', string $remark = '') { $withdraws = WithdrawCash::where('batch_payment_id', $batch_payment_id)->get(); foreach ($withdraws as $withdraw) { $this->updateWithdrawCashStatus($withdraw, $status, $uid, $serial_number, $remark); if (in_array($status, self::success_status)) { Payment::create([ 'withdraw_cash_id' => $withdraw->id, 'amount' => $withdraw->amount, 'remark' => '合并打款', 'pay_time' => date('Y-m-d H:i:s'), 'pay_merchant_source' => 'SANDPAY', 'trade_no' => $serial_number, 'status' => self::auto_success, 'is_company' => $withdraw->is_company ]); } } } /** * 更新合并打款状态 */ public function updateBatchPaymentStatus(BatchPayments $payment, string $status, int $uid = 0, array $query_result = [], string $serial_number = '') { try { DB::beginTransaction(); $payment->serial_number = $serial_number ? $serial_number : ($payment->serial_number ?? ''); $payment->status = $status; $payment->pay_merchant_source_msg = $query_result ? json_encode($query_result) : ''; $payment->pay_merchant_source_result = in_array($status, self::success_status) ? '处理成功' : ''; $payment->save(); $this->updateBatchPaymentWithdrawCashStatus($payment->id, $status, $uid, $payment->serial_number); DB::commit(); } catch (Exception $e) { myLog('test')->info($e->getTraceAsString()); DB::rollback(); } } /** * 查找自动待打款的批量提现记录 */ public function findPayingBatchPayments() { return BatchPayments::where('status', self::auto_paying)->get(); } public function findBatchPayment(int $batch_payment_id) { return BatchPayments::find($batch_payment_id); } /** * 设置打款的redis缓存 */ private function setRedis(string $redis_key, int $id) { Redis::sAdd($redis_key, $id); Redis::expire($redis_key, 60 * 60 * 24); } /** * 判断是否在合并打款中 */ public function judgeIsPayment($id) { $key = 'batch_payment:' . date('Y-m-d'); if (Redis::sIsmember($key, $id)) { return true; } else { $result = BatchPayments::where('id', $id)->whereIn('status', self::paying_status)->exists(); if ($result) { $this->setRedis($key, $id); } return $result; } } /** * 合并打款 * @param $uid * @param $batch_payment_id * @param $amount * @param $remark * @return bool */ public function makeThreeSourcePayment(BatchPayments $batch_payment, int $uid, float $amount, string $remark) { $trade_no = date('YmdHis') . ($batch_payment->channel_user_id); $pay_service = new SandPay; //对私 $balance = $pay_service->queryBalance([ 'order_no' => date('YmdHis'), 'pay_time' => $batch_payment->pay_time, ]); if ($balance > 0 && $balance >= $amount) { try { DB::beginTransaction(); $this->setRedis('batch_payment:' . date('Y-m-d'), $batch_payment->id); //修改状态打款中 $batch_payment->trade_no = $trade_no; $batch_payment->status = self::auto_paying; $batch_payment->pay_time = now(); $batch_payment->save(); $this->updateBatchPaymentWithdrawCashStatus($batch_payment->id, self::auto_paying, $uid, '', $remark); $result = $pay_service->agentPay([ 'order_no' => $trade_no, 'pay_time' => (string) $batch_payment->pay_time, 'account_name' => $batch_payment->account_name, 'bank_account' => $batch_payment->bank_account, 'account_bank' => $batch_payment->account_bank, 'remark' => $remark, 'amount' => $amount, ]); $batch_payment->pay_merchant_source_msg = json_encode($result); $batch_payment->save(); DB::commit(); return true; } catch (Exception $e) { Log::error($e->getTraceAsString()); DB::rollback(); } } } /** * 添加合并打款数据 */ private function addBatchPayment(string $status, float $amount, int $is_company, WithdrawCash $model, array $channel_ids, array $ids) { $payment = [ 'amount' => $amount, 'status' => self::wait_pay, 'is_company' => $is_company, 'channel_user_id' => $model->channel_user_id, 'bank_account' => $model->bank_account, 'account_name' => $model->account_name, 'account_bank' => $model->account_bank, 'remark' => "channel_ids:" . (implode(',', $channel_ids)) . ';withdraw_cash_ids:' . implode(',', $ids) ]; $added = BatchPayments::create($payment); WithdrawCash::whereIn('id', $ids)->update([ 'batch_payment_id' => $added->id, 'status' => $status ]); } /** * 查找待合并提现记录 * @return Collection */ private function findWaitMergeWithdrawCash(int $is_company) { $withdraws = WithdrawCash::where('distribution_channel_id', '>', 0) ->where('is_batch_operate', 1) ->where('is_company', $is_company) ->where('status', self::wait_merge) ->where(function ($query) { $query->whereNull('batch_payment_id')->orwhere('batch_payment_id', 0); }) ->get(); $channel_ids = $withdraws->pluck('distribution_channel_id')->all(); $channels = Channel::whereIn('id', $channel_ids)->select('id', 'channel_user_id')->get(); $withdraws->transform(function ($item) use ($channels) { $channel = $channels->where('id', $item->distribution_channel_id)->first(); $item->channel_user_id = $channel ? $channel->channel_user_id : 0; return $item; }); return $withdraws->sortByDesc('amount') ->sortBy('bank_account') ->sortBy('channel_user_id') ->sortBy('pay_merchant_company_id') ->values(); } public function mergePayments(int $is_company) { //获取排好序的待合并数据 $withdrawCashes = $this->findWaitMergeWithdrawCash($is_company); $amount = 0; $temp = $withdrawCashes->first(); $channel_ids = []; $ids = []; if (count($withdrawCashes) > 0) { try { DB::beginTransaction(); foreach ($withdrawCashes as $withdrawCash) { if ( $temp->channel_user_id == $withdrawCash->channel_user_id && $temp->bank_account == $withdrawCash->bank_account && $temp->pay_merchant_company_id == $withdrawCash->pay_merchant_company_id && $amount + $withdrawCash->amount < 50000 ) { $amount += $withdrawCash->amount; $ids[] = $withdrawCash->id; if (!in_array($withdrawCash->distribution_channel_id, $channel_ids)) $channel_ids[] = $withdrawCash->distribution_channel_id; } else { $this->addBatchPayment(self::auto_wait_pay, $amount, $is_company, $temp, $channel_ids, $ids); $amount = $withdrawCash->amount; $ids = []; $channel_ids = []; $ids[] = $withdrawCash->id; $channel_ids[] = $withdrawCash->distribution_channel_id; $temp = $withdrawCash; } } if ($amount > 0) { $this->addBatchPayment(self::auto_wait_pay, $amount, $is_company, $temp, $channel_ids, $ids); } DB::commit(); } catch (Exception $e) { myLog('add_batch_payment')->error($e->getMessage()); DB::rollBack(); } } } }