464 lines
18 KiB
PHP
464 lines
18 KiB
PHP
<?php
|
|
|
|
|
|
namespace App\Logic;
|
|
|
|
|
|
use App\AccountLog;
|
|
use App\CoinTrade;
|
|
use App\CurrencyQuotation;
|
|
use App\Setting;
|
|
use App\UsersWallet;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class CoinTradeLogic
|
|
{
|
|
public static function userSellCoin($userId,$sellCurrencyId,$wantCurrencyId,$amount,$price){
|
|
//第一步 找出钱包
|
|
$wallet = UsersWallet::where("user_id", $userId)
|
|
->where("currency", $sellCurrencyId)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
//锁钱包该币种数量
|
|
//获取当前价格
|
|
$qut = CurrencyQuotation::getInstance($wantCurrencyId,$sellCurrencyId);
|
|
DB::beginTransaction();
|
|
try{
|
|
// $price = bc_mul($amount,$price,8);
|
|
$result = change_wallet_balance($wallet,2, -$amount, AccountLog::COIN_TRADE_FROZEN, '币币交易下单,资金锁定');
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
|
|
change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
$amount,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易下单,锁定资金增加',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
//生成
|
|
CoinTrade::newTrade($userId,CoinTrade::TRADE_TYPE_SELL,$sellCurrencyId,$wantCurrencyId,$amount,$qut->now_price,$price);
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public static function userBuyCoint($userId,$buyCurrencyId,$payCurrencyId,$amount,$price){
|
|
//第一步 找出钱包
|
|
$wallet = UsersWallet::where("user_id", $userId)
|
|
->where("currency", $payCurrencyId)
|
|
->lockForUpdate()
|
|
->first();
|
|
//锁钱包该币种数量
|
|
$qut = CurrencyQuotation::getInstance($payCurrencyId,$buyCurrencyId);
|
|
// $costPrice = bc_mul($price,$amount);
|
|
|
|
$costPrice = $amount;
|
|
if($qut->now_price) $num = $amount / $qut->now_price;
|
|
DB::beginTransaction();
|
|
try{
|
|
// $price = bc_mul($amount,$price,8);
|
|
$result = change_wallet_balance($wallet,2, -$costPrice, AccountLog::COIN_TRADE_FROZEN, '币币交易下单,资金锁定');
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
|
|
change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
$costPrice,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易下单,锁定资金增加',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
//生成
|
|
CoinTrade::newTrade($userId,CoinTrade::TRADE_TYPE_BUY,$buyCurrencyId,$payCurrencyId,$num,$qut->now_price,$price);//$amount
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
// 生成订单
|
|
}
|
|
|
|
public static function matchSellTrade($currencyId,$legalId,$nowPrice){
|
|
|
|
if($currencyId==49) {
|
|
$tradeList = CoinTrade::where([
|
|
'currency_id' => $currencyId,
|
|
'legal_id' => $legalId,
|
|
'status' => 1,
|
|
'type' => 2
|
|
])->limit(1)->get();
|
|
}else{
|
|
|
|
$tradeList = CoinTrade::where([
|
|
'currency_id' => $currencyId,
|
|
'legal_id' => $legalId,
|
|
'status' => 1,
|
|
'type' => 2
|
|
])->where('target_price','<=',$nowPrice)->limit(1)->get();
|
|
}
|
|
|
|
foreach($tradeList as $trade){
|
|
DB::beginTransaction();
|
|
try{
|
|
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->legal_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
$targetWallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->currency_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
if(!$wallet || !$targetWallet){
|
|
throw new \Exception(sprintf('订单%s找不到用户钱包',$trade->id));
|
|
}
|
|
|
|
$costPrice = bc_mul($trade->target_price,$trade->trade_amount,8);
|
|
|
|
change_wallet_balance(
|
|
$targetWallet,
|
|
2,
|
|
-$trade->trade_amount,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易锁定减少',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
$chargeFee = $trade->charge_fee;
|
|
$chargeFee = bc_sub(1,$chargeFee,8);
|
|
//手续费
|
|
$costPrice = bc_mul($costPrice,$chargeFee,8);
|
|
change_wallet_balance($wallet,
|
|
2,
|
|
$costPrice,
|
|
AccountLog::COIN_TRADE,
|
|
'币币交易成功');
|
|
$trade->status = 2;
|
|
$trade->save();
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
echo $e->getMessage();
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function matchBuyTrade($currencyId,$legalId,$nowPrice){
|
|
$tradeList = CoinTrade::where([
|
|
'currency_id' => $currencyId,
|
|
'legal_id' => $legalId,
|
|
'status' => 1,
|
|
'type' => 1
|
|
])->where('target_price','>=',$nowPrice)->limit(1)->get();
|
|
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',json_encode($tradeList));
|
|
foreach($tradeList as $trade){
|
|
|
|
DB::beginTransaction();
|
|
try{
|
|
//1 扣掉锁定资金
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->legal_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',json_encode($wallet).PHP_EOL,FILE_APPEND);
|
|
|
|
$targetWallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->currency_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',time()."--".json_encode($targetWallet).PHP_EOL,FILE_APPEND);
|
|
if(!$wallet || !$targetWallet){
|
|
throw new \Exception(sprintf('订单%s找不到用户钱包',$trade->id));
|
|
}
|
|
$costPrice = bc_mul($trade->target_price,$trade->trade_amount,8);
|
|
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',$costPrice.PHP_EOL,FILE_APPEND);
|
|
|
|
change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
-$costPrice,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易成功,锁定资金减少',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
|
|
//手续费
|
|
$chargeFee = $trade->charge_fee;
|
|
$chargeFee = bc_sub(1,$chargeFee,8);
|
|
$amount = bc_mul($trade->trade_amount,$chargeFee,8);
|
|
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',$amount.PHP_EOL,FILE_APPEND);
|
|
change_wallet_balance($targetWallet,
|
|
2,
|
|
$amount,
|
|
AccountLog::COIN_TRADE,
|
|
'币币交易成功');
|
|
$trade->status = 2;
|
|
// if($currencyId==49)file_put_contents('/www/wwwroot/crypto/public/tt1.txt',$trade->status.PHP_EOL,FILE_APPEND);
|
|
|
|
$trade->save();
|
|
|
|
//解冻操作
|
|
if($currencyId == 29 && $trade->trade_amount > 50){
|
|
// echo 'int33333333333';
|
|
$price = bc_mul($trade->trade_amount,0.25,8);
|
|
// var_dump([$trade->user_id,$currencyId,$price]);
|
|
//获取账号锁定金额
|
|
$lh_account = DB::table('lh_bank_account')->where('uid',$trade->u_id)->first();
|
|
if($lh_account && $lh_account->coin_lock_balance > 0){
|
|
if($lh_account->coin_lock_balance > $price){
|
|
$coin_lock_balance = bc_sub($lh_account->coin_lock_balance,$price,8);
|
|
$amount = $price;
|
|
}else{
|
|
$coin_lock_balance = 0;
|
|
$amount = $lh_account->coin_lock_balance;
|
|
}
|
|
DB::table('lh_bank_account')->where('uid',$trade->u_id)->update([
|
|
'coin_lock_balance' => $coin_lock_balance
|
|
]);
|
|
DB::table('wallet_unlock_order')->insert([
|
|
'user_id' => $trade->u_id,
|
|
'wallet_id' => $targetWallet->id,
|
|
'currency_id' => $currencyId,
|
|
'amount' => $amount,
|
|
'created_at' => date("Y-m-d H:i:s"),
|
|
'handle_time' => date('Y-m-d H:i:s',strtotime('+1 day'))
|
|
]);
|
|
|
|
}
|
|
// $res = DB::table('wallet_unlock_order')->where('user_id',$trade->u_id)->where('currency_id',$currencyId)->where('status',1)->where('remain_amount','>',0)->orderBy('amount','desc')->first();
|
|
// if($res){
|
|
// DB::table('wallet_unlock_order')->where('id',$res->id)->update([
|
|
// 'status' => 2,
|
|
// 'handle_time'=>date("Y-m-d H:i:s",strtotime('+1 day'))
|
|
// ]);
|
|
// // $res->status = 2;
|
|
// // $res->handle_time = ;
|
|
// // $res->save();
|
|
// }
|
|
}
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
echo $e->getMessage().'333333333333333333'.PHP_EOL;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static function forceMatchTrade($tradeId){
|
|
$trade = CoinTrade::find($tradeId);
|
|
if($trade->status != 1){
|
|
throw new \Exception('状态异常');
|
|
}
|
|
DB::beginTransaction();
|
|
try{
|
|
switch ($trade->type){
|
|
case 1:
|
|
//1 扣掉锁定资金
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->legal_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
$targetWallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->currency_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
if(!$wallet || !$targetWallet){
|
|
throw new \Exception(sprintf('订单%s找不到用户钱包',$trade->id));
|
|
}
|
|
$costPrice = bc_mul($trade->target_price,$trade->trade_amount,8);
|
|
|
|
change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
-$costPrice,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易成功,锁定资金减少',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
|
|
//手续费
|
|
$chargeFee = $trade->charge_fee;
|
|
$chargeFee = bc_sub(1,$chargeFee,8);
|
|
$amount = bc_mul($trade->trade_amount,$chargeFee,8);
|
|
change_wallet_balance($targetWallet,
|
|
2,
|
|
$amount,
|
|
AccountLog::COIN_TRADE,
|
|
'币币交易成功');
|
|
$trade->status = 2;
|
|
$trade->save();
|
|
break;
|
|
case 2:
|
|
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->legal_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
$targetWallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->currency_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
if(!$wallet || !$targetWallet){
|
|
throw new \Exception(sprintf('订单%s找不到用户钱包',$trade->id));
|
|
}
|
|
|
|
$costPrice = bc_mul($trade->target_price,$trade->trade_amount,8);
|
|
|
|
change_wallet_balance(
|
|
$targetWallet,
|
|
2,
|
|
-$trade->trade_amount,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'币币交易锁定减少',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
$chargeFee = $trade->charge_fee;
|
|
$chargeFee = bc_sub(1,$chargeFee,8);
|
|
//手续费
|
|
$costPrice = bc_mul($costPrice,$chargeFee,8);
|
|
change_wallet_balance($wallet,
|
|
2,
|
|
$costPrice,
|
|
AccountLog::COIN_TRADE,
|
|
'币币交易成功');
|
|
$trade->status = 2;
|
|
$trade->save();
|
|
break;
|
|
}
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
}
|
|
|
|
public static function cancelTrade($id){
|
|
$trade = CoinTrade::find($id);
|
|
if(!$trade)
|
|
throw new \Exception('找不到订单');
|
|
if($trade->status != 1)
|
|
throw new \Exception('订单状态异常,请刷新列表。');
|
|
|
|
|
|
switch ($trade->type){
|
|
case 1:
|
|
DB::beginTransaction();
|
|
try{
|
|
//解除锁定 还钱
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->legal_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
$costPrice = bc_mul($trade->target_price,$trade->trade_amount,8);
|
|
$result = change_wallet_balance($wallet,
|
|
2,
|
|
$costPrice,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'取消币币交易,资金返还');
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
$result = change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
-$costPrice,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'取消币币交易,退换锁定资金',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
$trade ->status = 3;
|
|
$trade->save();
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
break;
|
|
case 2:
|
|
DB::beginTransaction();
|
|
try{
|
|
//解除锁定 还钱
|
|
$wallet = UsersWallet::where("user_id", $trade->u_id)
|
|
->where("currency", $trade->currency_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
$result = change_wallet_balance($wallet,2, $trade->trade_amount, AccountLog::COIN_TRADE_FROZEN, '取消币币交易');
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
|
|
$result = change_wallet_balance(
|
|
$wallet,
|
|
2,
|
|
-$trade->trade_amount,
|
|
AccountLog::COIN_TRADE_FROZEN,
|
|
'取消币币交易,退换锁定资金',
|
|
true,
|
|
0,
|
|
0,
|
|
serialize([])
|
|
);
|
|
if ($result !== true) {
|
|
throw new \Exception($result);
|
|
}
|
|
$trade ->status = 3;
|
|
$trade->save();
|
|
DB::commit();
|
|
}catch (\Exception $e){
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
break;
|
|
default:
|
|
throw new \Exception('类型有误');
|
|
}
|
|
return true;
|
|
}
|
|
}
|