Files
cycle_api/app/Models/Wallet/Platform/WalletPlatformBalanceTransactionModel.php
2024-03-08 01:14:04 +08:00

248 lines
11 KiB
PHP

<?php
namespace App\Models\Wallet\Platform;
use App\Exceptions\ModelException;
use App\Models\Wallet\Base\WalletBaseModel;
use App\Models\Wallet\Wallet\WalletCurrencyModel;
use App\Tools\Math;
use App\Tools\Times;
use App\Tools\Tools;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class WalletPlatformBalanceTransactionModel extends WalletBaseModel
{
protected $table = 'wallet_platform_balance_transaction';
protected $primaryKey = 'id';
protected $fillable = [
'id',
'type',
'status',
'platform_id',
'currency_id',
'currency_code',
'currency_type',
'from_wallet_addr_id',
'from_user_transaction_id',
'from_uid',
'wallet_addr',
'from_wallet_transaction_id',
'received_amount',
'entered_amount',
'fee_amount',
'before_total_amount',
'after_total_amount',
'desc_key',
'desc',
'remark',
'sign',
'created_at',
'updated_at',
];
const TYPE_USER_RECHARGE = 1;
const TYPE_USER_WITHDRAW = 2;
const TYPE_ADMIN_ADD = 3;
const TYPE_ADMIN_DEC = 4;
const TYPE = [
self::TYPE_USER_RECHARGE => '用户充值',
self::TYPE_USER_WITHDRAW => '用户提现',
self::TYPE_ADMIN_ADD => '管理员加',
self::TYPE_ADMIN_DEC => '管理员减',
];
const STATUS_WAITING_QUEUE = 1;
const STATUS_CHAIN_WAITING_CALLBACK = 2;
const STATUS_SUCCESS = 3;
const STATUS_FAIL = 4;
const STATUS = [
self::STATUS_WAITING_QUEUE => '等待队列',
self::STATUS_CHAIN_WAITING_CALLBACK => '链上等待回调',
self::STATUS_SUCCESS => '成功',
self::STATUS_FAIL => '失败',
];
function addPlatformTransaction(
$type,
$status,
$received_amount,
$entered_amount,
$platform_id,
$currency_code,
$from_uid = '',
$from_user_transaction_id = '',
$from_wallet_addr_id = '',
$wallet_addr = '',
$desc_key = '',
$desc = '',
$remark = '',
): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|bool
{
$received_amount = abs($received_amount);
$entered_amount = abs($entered_amount);
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$oWalletCurrencyModel = new WalletCurrencyModel();
$resWalletPlatformBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalance($platform_id, $currency_code);
if (!$resWalletPlatformBalanceModel) throw new ModelException('platform balance not found');
$resWalletCurrencyModel = $oWalletCurrencyModel->findByCode($currency_code);
if (!$resWalletCurrencyModel) throw new ModelException('currency_code error');
if (in_array($type, [self::TYPE_ADMIN_DEC, self::TYPE_USER_WITHDRAW])) {
if (Math::bcComp($resWalletPlatformBalanceModel->available_amount, $received_amount) == -1) throw new ModelException('platform balance not enough');
}
//提现费率计算
$fee_amount = 0;
if ($type == self::TYPE_USER_WITHDRAW) {
$fee_amount = $oWalletCurrencyModel->computeTransferRate($received_amount, $oWalletCurrencyModel->transfer_rate);
$entered_amount = Math::bcSub($received_amount, $fee_amount);
}
if($type == self::TYPE_USER_RECHARGE){
$fee_amount = Math::bcSub($received_amount, $entered_amount);
}
$insert = [
'type' => $type,
'status' => $status,
'platform_id' => $platform_id,
'currency_id' => $resWalletPlatformBalanceModel->currency_id,
'currency_code' => $resWalletPlatformBalanceModel->currency_code,
'currency_type' => $resWalletPlatformBalanceModel->currency_type,
'from_wallet_addr_id' => $from_wallet_addr_id,
'from_user_transaction_id' => $from_user_transaction_id,
'from_uid' => $from_uid,
'wallet_addr' => $wallet_addr,
'received_amount' => $received_amount,
'entered_amount' => $entered_amount,
'fee_amount' => $fee_amount,
'before_total_amount' => $resWalletPlatformBalanceModel->total_amount,
'after_total_amount' => Math::bcAdd($resWalletPlatformBalanceModel->total_amount, $entered_amount),
'desc_key' => $desc_key,
'desc' => $desc,
'remark' => $remark,
];
// $insert['sign'] = '';
$insert['created_at'] = Times::getNowDateTime();
$insert['updated_at'] = Times::getNowDateTime();
return $this->addItem($insert);
}
//增加提现账变并且冻结平台金额
function newWithdrawPlatformTransaction(
$amount,
$platform_id,
$currency_code,
$uid,
): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|bool
{
try {
Db::beginTransaction();
$resModel = $this->addPlatformTransaction(self::TYPE_USER_WITHDRAW, self::STATUS_WAITING_QUEUE, $amount,$amount, $platform_id, $currency_code,$uid);
if(!$resModel) throw new ModelException('addPlatformTransaction error');
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$res = $oWalletPlatformBalanceModel->findPlatformBalance($platform_id,$currency_code);
if (!$res) throw new ModelException('findPlatformBalance error');
$res = $oWalletPlatformBalanceModel->frozenAmountById($oWalletPlatformBalanceModel->id, $amount); //变更平台余额
if (!$res) throw new ModelException('frozenAmountById error');
Db::commit();
return $resModel;
}catch (\Exception $e) {
Db::rollBack();
Log::error('newWithdrawPlatformTransaction', ['code' => $e->getCode(), 'error' => $e->getMessage()]);
return false;
}
}
//成功提现处理
function withdrawSuccByUserTransactionId($user_transaction_id, $remark = ''): bool
{
try{
Db::beginTransaction();
$resModel = $this->findItemByWhere(['from_user_transaction_id' => $user_transaction_id, 'type' => self::TYPE_USER_WITHDRAW]);
if (!$resModel) return false;
if (!in_array($resModel->status, [self::STATUS_WAITING_QUEUE, self::STATUS_CHAIN_WAITING_CALLBACK])) return false;
$resModel->status = self::STATUS_SUCCESS;
if(!empty($remark)) $resModel->remark = $remark;
$resModel->updated_at = Times::getNowDateTime();
$res = $resModel->save();
if(!$res) throw new ModelException('save error');
//扣除平台冻结余额
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resWalletPlatformBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalance($resModel->platform_id, $resModel->currency_code);
if (!$resWalletPlatformBalanceModel) throw new ModelException('platform balance not found');
$res = $oWalletPlatformBalanceModel->decFrozenAmountById($resWalletPlatformBalanceModel->id, $resModel->received_amount);
if (!$res) throw new ModelException('incBalance error');
Db::commit();
return true;
}catch (\Exception $e){
Db::rollBack();
Log::error('withdrawSuccByUserTransactionIdErr', ['code' => $e->getCode(), 'error' => $e->getMessage()]);
return false;
}
}
//失败提现处理
function withdrawErrByUserTransactionId($user_transaction_id, $remark = ''): bool
{
try {
Db::beginTransaction();
$resModel = $this->findItemByWhere(['from_user_transaction_id' => $user_transaction_id, 'type' => self::TYPE_USER_WITHDRAW]);
if (!$resModel) throw new ModelException('user transaction not found');
if (!in_array($resModel->status, [self::STATUS_WAITING_QUEUE, self::STATUS_CHAIN_WAITING_CALLBACK])) throw new ModelException('status error');
//更改账变状态
$resModel->status = self::STATUS_FAIL;
if(!empty($remark)) $resModel->remark = $remark;
$res = $resModel->save();
if (!$res) throw new ModelException('save error');
//解冻平台余额
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resWalletPlatformBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalance($resModel->platform_id, $resModel->currency_code);
if (!$resWalletPlatformBalanceModel) throw new ModelException('platform balance not found');
$res = $oWalletPlatformBalanceModel->unFrozenAmountById($resWalletPlatformBalanceModel->id, $resModel->received_amount);
if (!$res) throw new ModelException('incBalance error');
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollBack();
Log::error('withdrawErrByUserTransactionIdErr', ['code' => $e->getCode(), 'error' => $e->getMessage()]);
return false;
}
}
function newRechargePlatformTransaction(
$resWalletAddrTransactionModel,
$resWalletPlatformUserTransactionModel,
$amount,
$platform_id,
$currency_code,
): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|bool
{
try {
Db::beginTransaction();
$resModel = $this->addPlatformTransaction(self::TYPE_USER_RECHARGE, self::STATUS_SUCCESS, $amount,$amount, $platform_id, $currency_code,$resWalletPlatformUserTransactionModel->uid,$resWalletPlatformUserTransactionModel->id,$resWalletAddrTransactionModel->wallet_addr_id,$resWalletAddrTransactionModel->wallet_addr);
if(!$resModel) throw new ModelException('addPlatformTransaction error');
$oWalletPlatformBalanceModel = new WalletPlatformBalanceModel();
$resWalletPlatformBalanceModel = $oWalletPlatformBalanceModel->findPlatformBalance($platform_id,$currency_code);
if (!$resWalletPlatformBalanceModel) throw new ModelException('findPlatformBalance error');
$res = $oWalletPlatformBalanceModel->incAvailableBalance($resWalletPlatformBalanceModel->id, $amount); //变更平台余额
if (!$res) throw new ModelException('frozenAmountById error');
Db::commit();
return $resModel;
}catch (\Exception $e) {
Db::rollBack();
Log::error('newWithdrawPlatformTransaction', ['code' => $e->getCode(), 'error' => $e->getMessage()]);
return false;
}
}
}