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); } }