|
|
<?php
namespace App\Controller\v3;
use App\Commons\Log;use App\Constants\v3\ErrorCode;use App\Constants\v3\LogLabel;use App\Constants\v3\UserType;use App\Controller\BaseController;use App\Exception\ErrorCodeException;use App\Model\v3\FinancialRecord;use App\Model\v3\Store;use App\Model\v3\StoreWithdrawal;use App\Model\v3\User;use App\Model\v3\UserBalance;use App\Service\v3\Interfaces\FinancialRecordServiceInterface;use App\Service\v3\Interfaces\PaymentServiceInterface;use Hyperf\DbConnection\Db;use Hyperf\Di\Annotation\Inject;use Hyperf\Snowflake\IdGeneratorInterface;use Hyperf\Utils\ApplicationContext;use Hyperf\Validation\ValidationException;
class WithdrawController extends BaseController{
/** * @Inject * @var Log */ protected $log;
/** * @Inject * @var FinancialRecordServiceInterface */ protected $financialService;
/** * @Inject * @var PaymentServiceInterface */ protected $paymentService;
/** * 商户提现页数据 * 1、可提现金额 * 2、获得的奖励金额(历史总奖励金额) * 3、用户须知 * 4、提现须知 */ public function pageByStore() { $validator = $this->validationFactory->make( $this->request->all(), [ 'user_id' => 'required|nonempty|integer', 'store_id' => 'required|nonempty|integer', ], ['*.*' => ':attribute 参数不正确'] );
if ($validator->fails()) { throw new ValidationException($validator); }
$userId = $this->request->input('user_id'); $storeId = $this->request->input('store_id'); $store = Store::query()->where(['user_id' => $userId, 'id' => $storeId])->first(); if (empty($store)) { throw new ErrorCodeException(ErrorCode::STORE_NOT_AVAILABLE); }
$data['balance'] = UserBalance::query() ->where(['source_id' => $store->user_id, 'user_type' => UserType::STORE]) ->value('balance');
$data['award'] = $this->financialService->sumAmount( $store->user_id, UserType::STORE, [FinancialRecord::MONEY_TYPE_STORE_PLAT_NEW_USER, FinancialRecord::MONEY_TYPE_STORE_FIRST_ORDER] );
$data['notice'] = [ [ 'title' => '用户须知', 'content' => '<p>请仔细填写相关信息,如果由于您填写的信息有误导致资金流失,平台概不负责。</p><p>注意:因微信限制当前用户账户余额满<span style="color:red;">1</span>元后才可提现</p>' ], [ 'title' => '提现须知', 'content' => '<p>一次提现金额最低为<span style="color:red;">1</span>元</p>' .'<p>一次提现金额最高为<span style="color:red;">5000</span>元</p>' .'<p>每天可提现<span style="color:red;">10</span>次</p>' ], ];
return $this->success($data); }
/** * 商户提现申请 * 1、商户提现参数校验 * 2、商户提现是否超过可提现金额 * 3、提现是否秒到账,秒到账则打款并且做流水,否则就打到后台审核 */ public function applyByStore() {
$isDirect = config('wechat.withdrawal.is_direct'); $min = config('wechat.withdrawal.min_amount'); $max = config('wechat.withdrawal.max_amount'); $validator = $this->validationFactory->make( $this->request->all(), [ 'user_id' => 'required|nonempty|integer', 'store_id' => 'required|nonempty|integer', 'money' => "required|nonempty|numeric|between:{$min}, {$max}", ] );
if ($validator->fails()) { throw new ValidationException($validator); }
$money = $this->request->input('money'); $userId = $this->request->input('user_id'); $storeId = $this->request->input('store_id'); $store = Store::query()->where(['user_id' => $userId, 'id' => $storeId])->first(); if (empty($store)) { throw new ErrorCodeException(ErrorCode::STORE_NOT_AVAILABLE, '[稍后重试]'); }
// 校验余额
$balance = UserBalance::query() ->where(['source_id' => $store->user_id, 'user_type' => UserType::STORE]) ->first(); if ($money > $balance->balance) { throw new ErrorCodeException(ErrorCode::STORE_WITHDRAW_INSUFFICIENT_BALANCE); }
Db::beginTransaction(); try {
$storeUser = User::query()->find($store->user_id); $currentTime = time();
// 获取分布式全局ID
$generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class); $globalOrderId = $generator->generate();
// 记录提现申请记录
$withdraw = new StoreWithdrawal(); $withdraw->trade_no = $globalOrderId; $withdraw->store_id = $store->id; $withdraw->name = $storeUser->real_name ?? $storeUser->nick_name; $withdraw->tel = $storeUser->tel; $withdraw->apply_cash = $money; $withdraw->save();
// 先扣除余额
$balance->balance = bcsub($balance->balance, $money, 2); $balance->save();
// 如果秒到账无需审核的话
if ($isDirect) { // 打款
$res = $this->paymentService->payToWx( bcmul($withdraw->apply_cash, 100 , 0), $withdraw->trade_no, $storeUser->openid, $withdraw->name, '商户提现打款' ); // 更新打款金额,审核时间等
$withdraw->check_time = time(); $withdraw->real_cash = $money; $withdraw->state = 2; $withdraw->save();
// 打款成功,写流水
if ($res === true) { $this->financialService->storeWithdrawByWx($store->user_id, $withdraw->id, $withdraw->real_cash); } }
Db::commit();
return $this->success([]); } catch (\Exception $e) { Db::rollBack(); $this->log->event(LogLabel::STORE_WITHDRAW_FAIL_LOG, [ 'msg' => $e->getMessage(), 'withdraw' => json_encode($withdraw), 'params' => json_encode(['balance' => $balance->balance, 'user_id' => $userId, 'store_id' => $storeId]), ]); throw new ErrorCodeException(ErrorCode::STORE_WITHDRAW_FAIL, '[请稍后重试]'.$e->getMessage()); }
}}
|