|
|
|
@ -2,26 +2,46 @@ |
|
|
|
|
|
|
|
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、可提现金额 |
|
|
|
@ -44,8 +64,8 @@ class WithdrawController extends BaseController |
|
|
|
throw new ValidationException($validator); |
|
|
|
} |
|
|
|
|
|
|
|
$userId = $this->request->input('user_id', 0); |
|
|
|
$storeId = $this->request->input('store_id', 0); |
|
|
|
$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); |
|
|
|
@ -77,13 +97,95 @@ class WithdrawController extends BaseController |
|
|
|
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' |
|
|
|
'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, |
|
|
|
'商户提现打款' |
|
|
|
); |
|
|
|
// 更新打款金额,审核时间等
|
|
|
|
} |
|
|
|
|
|
|
|
Db::commit(); |
|
|
|
|
|
|
|
return $this->success([]); |
|
|
|
} catch (\Exception $e) { |
|
|
|
Db::rollBack(); |
|
|
|
$this->log->event(LogLabel::STORE_WITHDRAW_FAIL_LOG, [ |
|
|
|
'exception' => $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()); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |