withdrawModel = $withdrawModel; $this->setAuditAmount(); $this->set = \Setting::get('withdraw.income'); } /** * 提现审核接口 * * @return bool * @throws ShopException */ public function withdrawAudit() { if ($this->withdrawModel->status == Withdraw::STATUS_INITIAL || $this->withdrawModel->status == Withdraw::STATUS_INVALID) { try { // 判断:如果存在冻结金额 不支持独立操作,必须全部统一操作 $operate[] = (int)count($this->withdrawModel->audit_ids) > 0; $operate[] = (int)count($this->withdrawModel->rebut_ids) > 0; $operate[] = (int)count($this->withdrawModel->invalid_ids) > 0; $operateSum = array_sum($operate); if($this->withdrawModel->freeze_money > 0 && $operateSum > 1){ throw new ShopException("存在冻结金额,仅支持全部统一操作,不支持每条信息单独存在!"); } return $this->_withdrawAudit(); } catch (\Exception $e) { event(new WithdrawFailedEvent($this->withdrawModel)); $this->sendMessage(); \Log::debug("提现审核失败ID{$this->withdrawModel->id}",$e->getMessage()); \Log::debug("提现审核失败ID{$this->withdrawModel->id}",$e->getTraceAsString()); throw new ShopException($e->getMessage(),"提现审核:ID{$this->withdrawModel->id}",); } } throw new ShopException("提现审核:ID{$this->withdrawModel->id},不符合审核规则"); } /** * @return bool */ private function _withdrawAudit() { DB::transaction(function () { // 减少冻结金额 $this->audit_amount = $this->audit_amount - $this->withdrawModel->freeze_money; // 计算实际提现信息 并且修改申请状态 $this->audit(); WithdrawIncomeApplyService::apply($this->withdrawModel,'backend'); // 判断:如果存在冻结金额 根据类型进行对应的解冻操作 $incomeFreezeSet = IncomeFreezeSet::getInfo($this->withdrawModel->member_id); $currentFreezeSet = $incomeFreezeSet[$this->withdrawModel->key_name]['set_info'] ?? []; if($this->withdrawModel->freeze_money > 0 && count($this->withdrawModel->audit_ids) > 0 && $currentFreezeSet){ switch($this->withdrawModel->key_name){ case 'shaerholderDividend': if($currentFreezeSet['freeze_type'] == 1){ // 独立设置 $levelList = $currentFreezeSet['level_list'] ?? []; $lvAmountList = ShareholderDividendModel::getIncome((int)$this->withdrawModel->member_id,(int)0) ->whereIn('yz_member_income.id',$this->withdrawModel->audit_ids) ->select(['yz_shareholder_dividend.team_level',DB::raw("sum(ims_yz_member_income.amount) as lv_sum_amount")]) ->groupBy('yz_shareholder_dividend.team_level') ->get() ->toArray(); foreach($lvAmountList as $lvAmountInfo){ // 当前等级设置的冻结金额 $lvSetFreezeMoney = $levelList[$lvAmountInfo['team_level']]['freeze_money'] ?? 0; // 判断:当前等级存在冻结金额;且提现佣金大于冻结金额 if($lvSetFreezeMoney > 0 && $lvAmountInfo['lv_sum_amount'] > $lvSetFreezeMoney){ // 解冻 $levelList[$lvAmountInfo['team_level']]['freeze_money'] = 0; } } $currentFreezeSet['level_list'] = $levelList; }else{ // 统一设置 $currentFreezeSet['total'] = 0; } break; } // 修改设置信息 $incomeFreezeSet[$this->withdrawModel->key_name]['set_info'] = $currentFreezeSet; IncomeFreezeSet::setInfo($this->withdrawModel->member_id,$incomeFreezeSet); } }); return true; } private function audit() { event(new WithdrawAuditEvent($this->withdrawModel)); $this->auditing(); } private function auditing() { $this->withdrawModel->status = $this->getAuditStatus(); $this->withdrawModel->audit_at = time(); $this->withdrawModel->actual_poundage = $this->getActualPoundage(); $this->withdrawModel->actual_servicetax = $this->getActualServiceTax(); $this->withdrawModel->actual_amounts = $this->getActualAmount(); event(new WithdrawAuditingEvent($this->withdrawModel)); $this->audited(); } private function getAuditStatus() { $type_ids_count = count(array_filter(explode(',', $this->withdrawModel->type_id))); //$audit_count = count($this->withdrawModel->audit_ids); $rebut_count = count($this->withdrawModel->rebut_ids); $invalid_count = count($this->withdrawModel->invalid_ids); //如果全无效 if ($invalid_count > 0 && $invalid_count == $type_ids_count) { return Withdraw::STATUS_INVALID; } //如果全驳回 if ($rebut_count > 0 && $rebut_count == $type_ids_count) { return Withdraw::STATUS_REBUT; } //如果是无效 + 驳回 [同全驳回,直接完成] if ($invalid_count > 0 && $rebut_count > 0 && ($invalid_count + $rebut_count) == $type_ids_count) { // return Withdraw::STATUS_PAY; return Withdraw::STATUS_REBUT; } return Withdraw::STATUS_AUDIT; } /** * @throws ShopException */ private function audited() { $validator = $this->withdrawModel->validator(); if ($validator->fails()) { throw new ShopException($validator->messages()->first()); } if (!$this->withdrawModel->save()) { throw new ShopException("提现审核:ID{$this->withdrawModel->id},记录更新失败"); } event(new WithdrawAuditedEvent($this->withdrawModel)); } /** * 审核后最终手续费 * * @return float */ private function getActualPoundage() { $amount = $this->audit_amount; $rate = $this->withdrawModel->poundage_rate; if ($this->withdrawModel->poundage_type == 1) { if ($amount != 0) { return $rate; } else { return 0; } } return bcdiv(bcmul($amount, $rate, 4), 100, 2); } /** * 审核后最终劳务税 * @return string * @throws ShopException */ private function getActualServiceTax() { $withdraw_set = \Setting::get('withdraw.income'); $audit_amount = $this->audit_amount; //收入总和 if (!$withdraw_set['service_tax_calculation']) { $poundage = $this->getActualPoundage(); //手续费 $audit_amount = bcsub($audit_amount, $poundage, 2); //收入总和减去手续费 } if ($audit_amount < 0 && $audit_amount != 0) { throw new ShopException("驳回部分后提现金额小于手续费,不能通过申请!"); } //计算劳务税 // $rate = $this->withdrawModel->servicetax_rate; $rate = $this->getLastActualServiceTax($audit_amount, $withdraw_set); $this->withdrawModel->servicetax_rate = $rate; return bcdiv(bcmul($audit_amount, $rate, 4), 100, 2); } /** * 审核后最终金额 * * @return float */ private function getActualAmount() { $amount = $this->audit_amount; $poundage = $this->getActualPoundage(); $service_tax = $this->getActualServiceTax(); return bcsub(bcsub($amount, $poundage, 2), $service_tax, 2); } private function setAuditAmount() { !isset($this->audit_amount) && $this->audit_amount = $this->auditIncomeAmount(); } /** * 审核通过的收入金额和 * * @return float */ private function auditIncomeAmount() { $audit_ids = $this->withdrawModel->audit_ids; $amount = Income::uniacid()->whereIn('id', $audit_ids)->sum('amount'); return $this->audit_amount = $amount; } /** * 增加劳务税梯度 * @param $amount * @return mixed */ private function getLastActualServiceTax($amount, $withdraw_set) { if (in_array($this->withdrawModel->type,Withdraw::$noDeductionServicetax)) {//这些提现不收劳务税 return 0; } if ($this->withdrawModel->pay_way != 'balance' || !$withdraw_set['balance_special']){ if ($merage_rate = WithdrawMergeServicetaxRate::uniacid()->where('withdraw_id', $this->withdrawModel->id)->where('is_disabled', 0)->first()) { return $merage_rate->servicetax_rate; } } $servicetax_rate = $withdraw_set['servicetax_rate']; if ($this->withdrawModel->servicetax_rate != $servicetax_rate) { return $this->withdrawModel->servicetax_rate; } $servicetax = $withdraw_set['servicetax']; if (empty($servicetax)) { return $servicetax_rate; } $max_money = array_column($servicetax, 'servicetax_money'); array_multisort($max_money, SORT_DESC, $servicetax); foreach ($servicetax as $value) { if ($amount >= $value['servicetax_money'] && !empty($value['servicetax_money'])) { return $value['servicetax_rate']; break; } } return $servicetax_rate; } private function sendMessage() { if ($this->set['free_audit'] == 1) { if ($this->withdrawModel->type == 'balance') { //余额提现失败通知 BalanceNoticeService::withdrawFailureNotice($this->withdrawModel); } else { $ids = \Setting::get('withdraw.notice.withdraw_user'); foreach ($ids as $k => $v) { (new MessageService($this->withdrawModel))->failureNotice($v['uid']); } } } } }