You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.7 KiB
201 lines
6.7 KiB
<?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->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());
|
|
}
|
|
|
|
}
|
|
}
|