paginate($request->input('limit', 20)); return $this->layuiData($data); } public function projectSave(Request $request) { $id = $request->input('id'); $fields = $request->only([ 'name','symbol','description','whitepaper_url','thumb_image', 'token_price','total_supply','min_buy','max_buy','start_time','end_time', 'type','status','fake_progress', 'subscription_limit','announce_time','listing_time','unlock_time' ]); // Normalize empty datetime strings to null to avoid MySQL errors foreach (['announce_time','listing_time','unlock_time','start_time','end_time'] as $k) { if (isset($fields[$k]) && $fields[$k] === '') $fields[$k] = null; } if ($id) { IeoProject::where('id', $id)->update($fields); } else { IeoProject::create($fields); } return $this->success('OK'); } public function projectDelete(Request $request) { IeoProject::destroy($request->input('id')); return $this->success('Deleted'); } public function orderList(Request $request) { $query = IeoOrder::query() ->leftJoin('users', 'ieo_order.user_id', '=', 'users.id') ->leftJoin('ieo_project', 'ieo_order.project_id', '=', 'ieo_project.id') ->select('ieo_order.*', 'users.phone as user_phone', 'users.email as user_email', 'ieo_project.name as project_name', 'ieo_project.symbol'); $project_id = $request->input('project_id'); if ($project_id) $query->where('ieo_order.project_id', $project_id); $data = $query->orderBy('ieo_order.id', 'desc')->paginate($request->input('limit', 20)); $statusMap = ['0'=>'待开奖','1'=>'已中签','2'=>'未中签']; $forceMap = [null=>'-','1'=>'强制中签','2'=>'强制未中']; foreach ($data as $item) { $item->status_text = $statusMap[$item->status] ?? ''; $item->force_text = $forceMap[$item->force_result] ?? '-'; } return $this->layuiData($data); } public function forceResult(Request $request) { $ids = $request->input('ids'); $result = $request->input('result'); // 1=win, 2=lose if (!$ids) return $this->error('No orders selected'); IeoOrder::whereIn('id', explode(',', $ids))->update(['force_result' => $result]); return $this->success('Set ' . ($result == 1 ? 'Force Win' : 'Force Lose')); } public function lottery(Request $request) { $project_id = $request->input('project_id'); $project = IeoProject::find($project_id); if (!$project) return $this->error('Project not found'); $orders = IeoOrder::where('project_id', $project_id)->where('status', 0)->get(); if ($orders->isEmpty()) return $this->error('No pending orders'); $won = 0; $lost = 0; DB::beginTransaction(); try { foreach ($orders as $order) { if ($order->force_result == 1) $result = 1; elseif ($order->force_result == 2) $result = 2; else $result = rand(1, 100) <= 50 ? 1 : 2; if ($result == 1) { $order->update(['status' => 1, 'token_amount' => $project->token_price > 0 ? sprintf("%.6f", $order->amount / $project->token_price) : 0]); $won++; } else { $wallet = UsersWallet::where('user_id', $order->user_id)->where('currency', 3)->first(); if ($wallet) { $before = $wallet->legal_balance; $wallet->legal_balance = bc_add($wallet->legal_balance, $order->amount, 6); $wallet->save(); AccountLog::insertLog( ['user_id'=>$order->user_id,'value'=>$order->amount,'info'=>'IEO Refund - '.$project->name,'type'=>AccountLog::IEO_OPERATION,'currency'=>3], ['balance_type'=>1,'wallet_id'=>$wallet->id,'lock_type'=>0,'before'=>$before,'change'=>$order->amount,'after'=>$wallet->legal_balance] ); } $order->update(['status' => 2]); $lost++; } } $creditOrders = \App\CreditIeoOrder::where('project_id', $project_id)->where('status', 0)->get(); $creditWon = 0; $creditLost = 0; foreach ($creditOrders as $co) { $cResult = rand(1, 100) <= 50 ? 1 : 2; if ($cResult == 1) { $co->update([ 'status' => 4, 'token_amount' => $project->token_price > 0 ? sprintf("%.6f", $co->amount / $project->token_price) : 0, ]); $creditWon++; } else { $line = \App\CreditLine::find($co->credit_line_id); if ($line) { $line->used_amount = max(0, bc_sub($line->used_amount, $co->amount, 6)); $line->available_amount = bc_add($line->available_amount, $co->amount, 6); if ($line->available_amount > $line->total_amount) $line->available_amount = $line->total_amount; $line->save(); } $co->update(['status' => 2]); $creditLost++; } } $project->update(['status' => 2]); DB::commit(); return $this->success("Lottery: {$won} won/{$lost} lost, Credit: {$creditWon} won/{$creditLost} lost"); } catch (\Exception $e) { DB::rollBack(); return $this->error($e->getMessage()); } } public function generateCodes(Request $request) { $project_id = intval($request->input('project_id')); $count = intval($request->input('count')); $amount = floatval($request->input('amount')); if (!$project_id || $count <= 0 || $amount <= 0) return $this->error('Invalid params'); if ($count > 1000) return $this->error('Max 1000 per batch'); $project = IeoProject::find($project_id); if (!$project) return $this->error('Project not found'); $generated = 0; $attempts = 0; $maxAttempts = $count * 5; while ($generated < $count && $attempts < $maxAttempts) { $attempts++; $code = strtoupper(substr(str_shuffle('ABCDEFGHJKLMNPQRSTUVWXYZ23456789'), 0, 6)); $exists = IeoAllocationCode::where('code', $code)->exists(); if ($exists) continue; IeoAllocationCode::create([ 'project_id' => $project_id, 'code' => $code, 'amount' => $amount, 'used' => 0, 'user_id' => 0, ]); $generated++; } return $this->success("Generated {$generated} codes"); } public function codeList(Request $request) { $project_id = $request->input('project_id'); $query = IeoAllocationCode::query() ->leftJoin('users', 'ieo_allocation_code.user_id', '=', 'users.id') ->leftJoin('ieo_project', 'ieo_allocation_code.project_id', '=', 'ieo_project.id') ->select('ieo_allocation_code.*', 'users.phone as user_phone', 'users.email as user_email', 'ieo_project.name as project_name'); if ($project_id) $query->where('ieo_allocation_code.project_id', $project_id); $data = $query->orderBy('ieo_allocation_code.id', 'desc')->paginate($request->input('limit', 50)); foreach ($data as $item) { $item->used_text = $item->used ? 'Used' : 'Available'; } return $this->layuiData($data); } }