Files
repo-backend/app/Http/Controllers/Api/IeoController.php
T

184 lines
8.2 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Api\Controller;
use App\IeoProject;
use App\IeoOrder;
use App\IeoAllocationCode;
use App\UsersWallet;
use App\AccountLog;
use Illuminate\Http\Request;
use App\Token;
use App\Users;
use Illuminate\Support\Facades\DB;
class IeoController extends Controller
{
public function list(Request $request)
{
$status = $request->input('status', 'all');
$query = IeoProject::query();
if ($status !== 'all') $query->where('status', $status);
$list = $query->orderBy('id', 'desc')->get();
foreach ($list as $item) {
$real_pct = $item->total_supply > 0 ? round($item->real_sold / $item->total_supply * 100, 2) : 0;
$item->progress = $item->type == 1 ? max($item->fake_progress, $real_pct) : min($item->fake_progress, 100);
}
return $this->success($list);
}
public function detail(Request $request)
{
$id = $request->input('id');
$project = IeoProject::find($id);
if (!$project) return $this->error('Not found');
$real_pct = $project->total_supply > 0 ? round($project->real_sold / $project->total_supply * 100, 2) : 0;
$project->progress = $project->type == 1 ? max($project->fake_progress, $real_pct) : min($project->fake_progress, 100);
$user_id = Token::getUserIdByToken(Token::getToken());
$user = \App\Users::find($user_id);
$project->my_order = null;
$project->my_order_count = 0;
if ($user) {
$order = IeoOrder::where('user_id', $user->id)->where('project_id', $id)->orderBy('id', 'desc')->first();
if ($order) {
$statusMap = ['0' => 'Pending', '1' => 'Won', '2' => 'Lost'];
$order->status_text = $statusMap[$order->status] ?? '';
$project->my_order = $order;
}
$project->my_order_count = IeoOrder::where('user_id', $user->id)->where('project_id', $id)->count();
}
return $this->success($project);
}
public function subscribe(Request $request)
{
$user_id = Token::getUserIdByToken(Token::getToken());
$user = \App\Users::find($user_id);
if (!$user) return $this->error('Please login');
$project_id = $request->input('project_id');
$amount = floatval($request->input('amount'));
$pay_pwd = $request->input('pay_pwd');
if ($amount <= 0) return $this->error('Invalid amount');
$project = IeoProject::find($project_id);
if (!$project || $project->status != 1) return $this->error('IEO not active');
if ($amount < $project->min_buy) return $this->error('Min: ' . $project->min_buy . ' USDC');
if ($project->max_buy > 0 && $amount > $project->max_buy) return $this->error('Max: ' . $project->max_buy . ' USDC');
$limit = intval($project->subscription_limit);
if ($limit > 0) {
$userOrderCount = IeoOrder::where('user_id', $user->id)->where('project_id', $project_id)->count();
if ($userOrderCount >= $limit) return $this->error('Subscription limit reached: ' . $limit);
}
$existingCredit = \App\CreditIeoOrder::where('user_id', $user->id)->where('project_id', $project_id)->whereIn('status', [0, 1])->exists();
if ($existingCredit) return $this->error('Already subscribed via credit IEO');
$wallet = UsersWallet::where('user_id', $user->id)->where('currency', 3)->lockForUpdate()->first();
if (!$wallet || $wallet->legal_balance < $amount) return $this->error('Insufficient balance');
DB::beginTransaction();
try {
$before = $wallet->legal_balance;
$wallet->legal_balance = bc_sub($wallet->legal_balance, $amount, 6);
$wallet->save();
AccountLog::insertLog(
['user_id' => $user->id, 'value' => -$amount, 'info' => 'IEO Subscribe - ' . $project->name, 'type' => AccountLog::IEO_OPERATION, 'currency' => 3],
['balance_type' => 1, 'wallet_id' => $wallet->id, 'lock_type' => 0, 'before' => $before, 'change' => -$amount, 'after' => $wallet->legal_balance]
);
$token_amount = $project->token_price > 0 ? sprintf("%.6f", $amount / $project->token_price) : 0;
IeoOrder::create([
'user_id' => $user->id, 'project_id' => $project_id,
'amount' => $amount, 'token_amount' => $token_amount, 'status' => 0,
]);
$project->increment('real_sold', $token_amount);
DB::commit();
return $this->success('Subscription successful');
} catch (\Exception $e) {
DB::rollBack();
return $this->error($e->getMessage());
}
}
public function myOrders(Request $request)
{
$user_id = Token::getUserIdByToken(Token::getToken());
$user = \App\Users::find($user_id);
if (!$user) return $this->error('Please login');
$list = IeoOrder::where('user_id', $user->id)->with('project:id,name,symbol')->orderBy('id', 'desc')->get();
$statusMap = ['0' => 'Pending', '1' => 'Won', '2' => 'Lost'];
foreach ($list as $item) {
$item->status_text = $statusMap[$item->status] ?? '';
}
return $this->success($list);
}
public function redeemCode(Request $request)
{
$user_id = Token::getUserIdByToken(Token::getToken());
$user = \App\Users::find($user_id);
if (!$user) return $this->error('Please login');
$code = trim((string)$request->input('code'));
$project_id = intval($request->input('project_id'));
if ($code === '' || !$project_id) return $this->error('Invalid params');
$project = IeoProject::find($project_id);
if (!$project || $project->status != 1) return $this->error('IEO not active');
DB::beginTransaction();
try {
$allocCode = IeoAllocationCode::where('project_id', $project_id)
->where('code', $code)
->lockForUpdate()
->first();
if (!$allocCode) { DB::rollBack(); return $this->error('Invalid code'); }
if ($allocCode->used) { DB::rollBack(); return $this->error('Code already used'); }
$amount = floatval($allocCode->amount);
if ($amount <= 0) { DB::rollBack(); return $this->error('Invalid code amount'); }
$wallet = UsersWallet::where('user_id', $user->id)->where('currency', 3)->first();
if (!$wallet || $wallet->legal_balance < $amount) { DB::rollBack(); return $this->error('Insufficient balance'); }
$before = $wallet->legal_balance;
$wallet->legal_balance = bc_sub($wallet->legal_balance, $amount, 6);
$wallet->save();
AccountLog::insertLog(
['user_id' => $user->id, 'value' => -$amount, 'info' => 'IEO Allocation - ' . $project->name, 'type' => AccountLog::IEO_OPERATION, 'currency' => 3],
['balance_type' => 1, 'wallet_id' => $wallet->id, 'lock_type' => 0, 'before' => $before, 'change' => -$amount, 'after' => $wallet->legal_balance]
);
$token_amount = $project->token_price > 0 ? sprintf("%.6f", $amount / $project->token_price) : 0;
IeoOrder::create([
'user_id' => $user->id, 'project_id' => $project_id,
'amount' => $amount, 'token_amount' => $token_amount, 'status' => 1,
]);
$project->increment('real_sold', $token_amount);
$allocCode->used = 1;
$allocCode->user_id = $user->id;
$allocCode->save();
DB::commit();
return $this->success('Redeemed successfully');
} catch (\Exception $e) {
DB::rollBack();
return $this->error($e->getMessage());
}
}
public function allocationOrders(Request $request)
{
$user_id = Token::getUserIdByToken(Token::getToken());
$user = \App\Users::find($user_id);
if (!$user) return $this->error('Please login');
$list = IeoAllocationCode::where('user_id', $user->id)
->where('used', 1)
->with('project:id,name,symbol,token_price,listing_time,unlock_time')
->orderBy('id', 'desc')
->get();
return $this->success($list);
}
}