From 3a10c3e2d72167fd8cf6a8fc8d45eb221fe95d8d Mon Sep 17 00:00:00 2001 From: pbao9 Date: Fri, 13 Feb 2026 12:03:11 +0700 Subject: [PATCH] refactor: remove unused `Type` components and relocate module-related API routes to admin routes. --- .../Controllers/frontend/ShopController.php | 2 - app/Providers/RepositoryProvider.php | 2 - app/View/Components/Order/Type.php | 5 +- app/View/Components/Type.php | 31 - .../pages/package/group/edit.blade.php | 2 +- .../pages/product/group.blade.php | 1 - .../components/module/datacenter.blade.php | 2 +- .../views/components/module/host.blade.php | 8 +- .../views/components/order/type.blade.php | 16 - resources/views/components/type.blade.php | 13 - routes/admin.php | 18 + routes/api.php | 1479 +---------------- 12 files changed, 27 insertions(+), 1552 deletions(-) delete mode 100644 app/View/Components/Type.php delete mode 100644 resources/views/components/order/type.blade.php delete mode 100644 resources/views/components/type.blade.php diff --git a/app/Http/Controllers/frontend/ShopController.php b/app/Http/Controllers/frontend/ShopController.php index 1e62ccc..1d4ee01 100644 --- a/app/Http/Controllers/frontend/ShopController.php +++ b/app/Http/Controllers/frontend/ShopController.php @@ -16,14 +16,12 @@ use App\Repositories\Addon\AddonRepositoryInterface; use App\Repositories\Domain\DomainRepositoryInterface; use App\Repositories\Group\GroupRepositoryInterface; use App\Repositories\Hosting\HostingRepositoryInterface; -use App\Repositories\Type\TypeRepositoryInterface; use App\Repositories\VPS\VPSRepositoryInterface; use Illuminate\Http\Request; class ShopController extends Controller { public function __construct( - public TypeRepositoryInterface $typeRepository, public GroupRepositoryInterface $groupRepository, public VPSRepositoryInterface $vpsRepository, public HostingRepositoryInterface $hostingRepository, diff --git a/app/Providers/RepositoryProvider.php b/app/Providers/RepositoryProvider.php index 76262ce..ae8577e 100644 --- a/app/Providers/RepositoryProvider.php +++ b/app/Providers/RepositoryProvider.php @@ -88,8 +88,6 @@ use App\Repositories\Module\Snapshot\SnapshotLimitRepositoryInterface; use App\Repositories\Module\Snapshot\SnapshotRepositoryInterface; use App\Repositories\Module\Vmware\VmwareCachedRepository; use App\Repositories\Module\Vmware\VmwareRepositoryInterface; -use App\Repositories\Type\TypeCachedRepository; -use App\Repositories\Type\TypeRepositoryInterface; use App\Repositories\Admin\Product\ProductRepository; use App\Repositories\Admin\Product\ProductRepositoryInterface; use App\Repositories\User\UserCachedRepository; diff --git a/app/View/Components/Order/Type.php b/app/View/Components/Order/Type.php index 82e03bf..5395bd4 100644 --- a/app/View/Components/Order/Type.php +++ b/app/View/Components/Order/Type.php @@ -2,7 +2,6 @@ namespace App\View\Components\Order; -use App\Repositories\Type\TypeRepositoryInterface; use Closure; use Illuminate\Contracts\View\View; use Illuminate\View\Component; @@ -13,7 +12,7 @@ class Type extends Component * Create a new component instance. */ public function __construct( - public TypeRepositoryInterface $typeRepository + // public TypeRepositoryInterface $typeRepository ) { // @@ -24,7 +23,7 @@ class Type extends Component */ public function render(): View|Closure|string { - $types= $this->typeRepository->getAll(); + $types = null; return view('components.order.type',compact('types')); } } diff --git a/app/View/Components/Type.php b/app/View/Components/Type.php deleted file mode 100644 index cebeb64..0000000 --- a/app/View/Components/Type.php +++ /dev/null @@ -1,31 +0,0 @@ -typeRepository->getAll(); - return view('components.type',compact('types')); - } -} diff --git a/resources/views/administrator/pages/package/group/edit.blade.php b/resources/views/administrator/pages/package/group/edit.blade.php index 68f48af..a51f550 100644 --- a/resources/views/administrator/pages/package/group/edit.blade.php +++ b/resources/views/administrator/pages/package/group/edit.blade.php @@ -43,7 +43,7 @@ {{-- Thumbnail using component --}} - + {{-- Status --}} diff --git a/resources/views/administrator/pages/product/group.blade.php b/resources/views/administrator/pages/product/group.blade.php index 892df2c..25b38f2 100644 --- a/resources/views/administrator/pages/product/group.blade.php +++ b/resources/views/administrator/pages/product/group.blade.php @@ -77,7 +77,6 @@ value="{{ old('slug') }}" class="form-control"> - {{--Status--}}
diff --git a/resources/views/components/module/datacenter.blade.php b/resources/views/components/module/datacenter.blade.php index 17360da..baa901a 100644 --- a/resources/views/components/module/datacenter.blade.php +++ b/resources/views/components/module/datacenter.blade.php @@ -64,7 +64,7 @@ if (!$selectedDatacenterId && $model) { $datacenter.html('').prop('disabled', true); $.ajax({ - url: '{{ route('api.getDatacenter') }}', + url: '{{ route('module-vcenter.getDatacenter') }}', type: 'GET', data: { vcenter: vcenterId diff --git a/resources/views/components/module/host.blade.php b/resources/views/components/module/host.blade.php index e7f8108..79d9cb5 100644 --- a/resources/views/components/module/host.blade.php +++ b/resources/views/components/module/host.blade.php @@ -29,10 +29,10 @@ $selectedHostId = old('module_host_id') ?? ($model?->module_host_id ?? ($model?- const $datacenter = $('.datacenter_id'); const $host = $('.host_id'); - + // Debounce function to prevent spam API calls let loadHostsTimeout; - + function debounceLoadHosts(datacenterId, preselect = null) { clearTimeout(loadHostsTimeout); loadHostsTimeout = setTimeout(() => { @@ -45,7 +45,7 @@ $selectedHostId = old('module_host_id') ?? ($model?->module_host_id ?? ($model?- if ($host.prop('disabled') && $host.find('option:first').text().includes('Đang tải')) { return; } - + if (!datacenterId) { $host.html('').prop('disabled', true); return; @@ -54,7 +54,7 @@ $selectedHostId = old('module_host_id') ?? ($model?->module_host_id ?? ($model?- $host.html('').prop('disabled', true); $.ajax({ - url: '{{ route('api.getHost') }}', + url: '{{ route('module-vcenter.getHost') }}', type: 'GET', data: { datacenter: datacenterId diff --git a/resources/views/components/order/type.blade.php b/resources/views/components/order/type.blade.php deleted file mode 100644 index 85a5ca5..0000000 --- a/resources/views/components/order/type.blade.php +++ /dev/null @@ -1,16 +0,0 @@ -
- -
- -
-
\ No newline at end of file diff --git a/resources/views/components/type.blade.php b/resources/views/components/type.blade.php deleted file mode 100644 index 9a3d819..0000000 --- a/resources/views/components/type.blade.php +++ /dev/null @@ -1,13 +0,0 @@ -{{--Last name--}} -
- -
- -
-
\ No newline at end of file diff --git a/routes/admin.php b/routes/admin.php index c154831..900c6b5 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -35,6 +35,8 @@ use App\Http\Controllers\admin\TaskController; use App\Http\Controllers\admin\TemplateController; use App\Http\Controllers\admin\UserController; use App\Http\Controllers\admin\vm\VirtualMachineController; +use App\Http\Controllers\Api\VpsActionController; +use App\Http\Controllers\rest\ModuleController; use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; @@ -448,5 +450,21 @@ Route::prefix('')->group(function () { Route::put('edit-menu/{id}', 'update')->name('menu.update'); Route::delete('remove-menu/{id}', 'destroy')->name('menu.destroy'); }); + + + Route::controller(ModuleController::class)->as('module-vcenter.')->group(function () { + Route::get('get-list-vcenter', 'getVCenter')->name('getVCenter'); + Route::get('get-list-datacenter', 'getDatacenter')->name('getDatacenter'); + Route::get('get-list-host', 'getHost')->name('getHost'); + Route::get('get-list-datastore', 'getDatastore')->name('getDatastore'); + Route::get('get-list-network', 'getNetwork')->name('getNetwork'); + Route::get('get-list-ipaddress', 'getIpAddress')->name('getIPAddress'); + Route::get('get-list-version-os', 'getOsServerVersion')->name('getVersion'); + Route::get('get-list-os-group', 'getOsGroup')->name('getOsGroup'); + }); + + Route::controller(VpsActionController::class)->group(function () { + Route::post('rebuild-vps', 'rebuildVps')->name('rebuildVps'); + }); }); }); \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 02bab65..d12d66a 100644 --- a/routes/api.php +++ b/routes/api.php @@ -50,1491 +50,14 @@ Route::prefix('v1') /* Api for Admin */ ->group(function () { Route::prefix('system')->middleware(['api.auth'])->group(function () { - Route::controller(ModuleController::class)->group(function () { - Route::get('get-list-vcenter', 'getVCenter')->name('api.getVCenter'); - Route::get('get-list-datacenter', 'getDatacenter')->name('api.getDatacenter'); - Route::get('get-list-host', 'getHost')->name('api.getHost'); - Route::get('get-list-datastore', 'getDatastore')->name('api.getDatastore'); - Route::get('get-list-network', 'getNetwork')->name('api.getNetwork'); - Route::get('get-list-ipaddress', 'getIpAddress')->name('api.getIPAddress'); - Route::get('get-list-version-os', 'getOsServerVersion')->name('api.getVersion'); - Route::get('get-list-os-group', 'getOsGroup')->name('api.getOsGroup'); - }); - - Route::post('rebuild-vps', [\App\Http\Controllers\Api\VpsActionController::class, 'rebuildVps']) - ->name('api.system.rebuildVps'); - - Route::get('get-list-product', function () { - $type_id = \request()->get('type'); - if (!$type_id) { - return response()->json(['error' => true, 'message' => 'Please choose Type']); - } - - if ($type_id === 1 || $type_id === 2) { - return response()->json(['error' => true, 'message' => 'Not Found']); - } - - $model = null; - - switch ($type_id) { - - case 3: - $model = Hosting::select('id', 'name', 'price', 'price_sale')->get(); - break; - case 4: - - $model = VPS::select('id', 'name', 'price', 'price_sale', 'module_host_id')->get(); - break; - default: - break; - } - - if (!$model) { - return response()->json(['error' => true, 'message' => 'Not Found']); - } - - return response()->json(['error' => false, 'data' => $model->all()]); - })->name('api.getProduct'); - Route::get('get-list-product-type', function () { - $type = Type::select('id', 'name')->get(); - return response()->json(['error' => false, 'data' => $type->all()]); - })->name('api.getProductType'); - - Route::get('get-ticket-console', function (Request $request, ServiceVCenter $serviceVCenter) { - $product_id = $request->get('product'); - if (!$product_id) { - return response()->json(['error' => true, 'message' => "Please choose product"]); - } - $product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id); - if (!$product) { - return response()->json(['error' => true, 'message' => "Can't find product"]); - } - - $vcenter = null; - if ($product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter) { - $vcenter = $product->ipAddress->host->datacenter->vCenter; - } - - if (!$vcenter) { - return response()->json(['error' => true, 'message' => "Can't find vCenter information"]); - } - - // Đăng nhập vCenter trước khi lấy ticket - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ]); - } - - $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); - - // Nếu login hết hạn, thử login lại 1 lần nữa - if ($ConsoleTicket === 'Login_Again') { - if ($serviceVCenter->loginServer($vcenter)) { - $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); - } else { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập lại vào vCenter' - ]); - } - } - - // Nếu vẫn lỗi, trả về lỗi rõ ràng - if (is_string($ConsoleTicket)) { - return response()->json([ - 'error' => true, - 'message' => "Failed to get console ticket: $ConsoleTicket" - ]); - } - - if ($ConsoleTicket['error']) { - return response()->json([ - 'error' => true, - 'message' => $ConsoleTicket['data'] - ]); - } - - return response()->json([ - 'error' => false, - 'data' => $ConsoleTicket['data'], - 'host' => $vcenter->host, - 'vmware-api-session-id' => $serviceVCenter->token - ])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false); - })->name('api.GetConsoleTicket'); - - Route::get('get-version-os', function () { - $group_id = \request()->get('group'); - if (!$group_id) { - return response()->json(['error' => true, 'message' => 'Please choose Host']); - } - $group_os = OsGroup::find($group_id); - - if (!$group_os) { - return response()->json(['error' => true, 'message' => 'Can\'t find Group Os']); - } - - $os = Os::where('os_group_id', $group_id)->select('id', 'version')->get(); - if ($os->count()) { - $os = array_map(function ($array) { - $array['name'] = $array['version']; - unset($array['version']); - return $array; - }, $os->all()); - return response()->json(['error' => false, 'data' => $os]); - } - return response()->json(['error' => true, 'message' => 'Can\'t find Os by Os Group ID #' . $group_id]); - })->name('api.GetVersionOs'); + Route::post('get-all-image', function (Media $media) { $files = $media->getAllMedia(); $data = view('administrator.pages.component.media')->with('media', $files)->render(); return response()->json(['data' => $data]); })->name('api.GetAllImage'); - Route::get('get-list-addon', function () { - $product = request()->input('product'); - if (!$product) { - return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']); - } - $allAddon = Addon::get(); - $formAddon = view('administrator.pages.component.addon')->with([ - 'addon' => $allAddon - ])->render(); - - return response()->json(['error' => false, 'data' => $formAddon]); - })->name('api.GetAddonProduct'); - Route::post('add-addon-to-product', function (Request $request) { - $order = $request->order; - $product = $request->product; - $cpu = $request->cpu; - $ram = $request->ram; - $ssd = $request->ssd; - if (!$cpu && !$ram && !$ssd) { - return response()->json(['error' => true, 'message' => 'Invalid Request']); - } - if (!$product) { - return response()->json(['error' => true, 'message' => 'Invalid Request']); - } - $product = ModuleVmware::find($request->product); - - if (!$product) { - return response()->json(['error' => true, 'message' => 'Invalid Request']); - } - - if ($order && $order != $product->order_id) { - return response()->json(['error' => true, 'message' => 'Invalid Request']); - } - $invoice_id = 0; - $billing_sw = 0; - $order = \App\Models\Order::with('OrderItem')->find($product->order_id); - if ($order && $order->OrderItem) { - $order_item = $order->OrderItem->first(); - $invoice_id = $order_item->invoice_id; - $billing_sw = $order_item->billing; - } - $invoice = Invoice::find($invoice_id); - - if (!$invoice) { - return response()->json(['error' => true, 'message' => 'Invalid Request']); - } - - $addon = []; - $item = []; - $total = 0; - if ($cpu) { - $item['cpu'] = $cpu; - } - if ($ram) { - $item['ram'] = $ram; - } - if ($ssd) { - $item['ssd'] = $ssd; - } - foreach ($item as $key => $value) { - $addonItem = Addon::where('name', 'like', "%$key%")->first(); - - $message = "Addon " . strtoupper($key); - switch ($billing_sw) { - case 2: - $billing = 1; - $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(1)->format('d/m/Y') . " )"; - break; - case 3: - $billing = 3; - $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(3)->format('d/m/Y') . " )"; - break; - case 4: - $billing = 6; - $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(6)->format('d/m/Y') . " )"; - break; - case 5: - $billing = 12; - $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(12)->format('d/m/Y') . " )"; - break; - } - $addon[] = [ - 'customer_id' => $product->customer_id, - 'type_id' => 1, - 'due_date' => Carbon::now()->hour(23)->minute(59)->second(59)->timestamp, - 'product_id' => $addonItem->id, - 'parent_id' => $product->id, - 'relid' => 0, - 'description' => $message, - 'invoice_type' => "1", - 'billing' => $billing_sw, - 'amount' => $addonItem->price * $value * $billing, - 'tax' => 1, - ]; - $total += $addonItem->price * $value * $billing; - } - try { - DB::beginTransaction(); - if ($order !== 0) { - $order->increment('amount', ($total + (0.1 * $total))); - $invoice->increment('total', ($total + (0.1 * $total))); - $invoice->increment('tax', 0.1 * $total); - $invoice->increment('sub_total', $total); - $product->increment('first_payment', $total); - $product->increment('next_payment', $total); - $allAddon = array_map(function ($item) use ($invoice) { - $item['invoice_id'] = $invoice->id; - return $item; - }, $addon); - InvoiceItem::insert($allAddon); - - $addonInsert = InvoiceItem::select('id')->latest('id')->take(count($allAddon))->get(); - - foreach ($addonInsert as $item) { - DB::table('order__order_item')->insert([ - 'order_id' => $order->id, - 'InvoiceItem_id' => $item->id - ]); - } - } else { - $invoice_added = Invoice::insertGetId([ - 'date' => Carbon::now()->timestamp, - 'due_date' => $product->next_due_date, - 'sub_total' => $total, - 'tax' => $total * 0.1, - 'total' => $total + ($total * 0.1), - 'payment_id' => 1, - 'customer_id' => $product->customer_id, - 'invoice_type' => 1, - 'status' => 0 - ]); - $order_id = \App\Models\Order::insertGetId([ - 'order_num' => App\Http\Helpers\Helper::generateUniqueCode(), - 'customer_id' => $product->customer_id, - 'user_id' => $request->user()->id, - 'date' => Carbon::now()->timestamp, - 'payment_id' => 1, - 'invoice_id' => $invoice_added, - 'amount' => $total + ($total * 0.1), - 'client_ip' => $request->getClientIp(), - 'status' => 0 - ]); - - $allAddon = array_map(function ($item) use ($invoice_added) { - $item['invoice_id'] = $invoice_added; - return $item; - }, $addon); - - InvoiceItem::insert($allAddon); - - $addonInsert = InvoiceItem::select('id')->latest('id')->take(count($allAddon))->get(); - - foreach ($addonInsert as $item) { - DB::table('order__order_item')->insert([ - 'order_id' => $order_id, - 'InvoiceItem_id' => $item->id - ]); - } - } - DB::commit(); - } catch (Exception $exception) { - DB::rollBack(); - return response()->json(['error' => true, 'message' => $exception->getMessage()]); - } - return response()->json(['error' => false, 'message' => 'Added Addon to Product Successfully']); - })->name('api.AcceptAddon'); - Route::post('create-slug', function (Request $request) { - return Str::slug($request->get('name')); - })->name('api.CreateSlug'); - Route::post('get-service-product', function (Request $request) { - $validate = Validator::make( - $request->all(), - [ - 'host' => 'required|numeric' - ] - ); - if ($validate->failed()) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - $host = ModuleHost::with('Datacenter.vCenter')->find($request->host); - - if (!$host) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - - $datacenter = ModuleDatacenter::where('vcenter_id', $host->Datacenter->vcenter_id)->select( - 'id', - 'name' - )->get(); - $allHost = ModuleHost::where('module_datacenter_id', $host->module_datacenter_id)->select( - 'id', - 'name' - )->get(); - $vcenter = vCenter::select('id', 'host')->get(); - - return response()->json([ - 'error' => false, - 'data' => [ - 'host' => $allHost, - 'datacenter' => $datacenter, - 'vcenter' => $vcenter, - 'choose' => [ - 'datacenter' => $host->module_datacenter_id, - 'vcenter' => $host->Datacenter->vcenter_id, - 'host' => $request->host - ] - ] - ]); - })->name('api.GetServiceProduct'); - Route::post('update-file-customer', function (Request $request) { - $validate = Validator::make( - $request->all(), - [ - 'user_id' => 'required|numeric', - 'file' => 'required|string' - ] - ); - if ($validate->failed()) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - $user = Customer::find($request->user_id); - - if (!$user) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - $fileName = str_replace(env('APP_URL') . '/uploads/files/', '', $request->file); - - $file = File::insertGetId([ - 'filename' => $fileName, - 'file_url' => $request->file, - 'customer_id' => $request->user_id - ]); - - if ($file) { - return response()->json(['error' => false, 'message' => 'New file updated successfully']); - } - return response()->json(['error' => true, 'message' => 'Invalid request']); - })->name('api.CustomerUpdateFile'); - Route::post('remove-file-customer', function (Request $request) { - $validate = Validator::make( - $request->all(), - [ - 'file' => 'required|numeric' - ] - ); - if ($validate->failed()) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - $file = File::find($request->file); - - if (!$file) { - return response()->json(['error' => true, 'message' => 'Invalid request']); - } - - $file->delete(); - - return response()->json(['error' => false, 'message' => 'The request was processed successfully']); - })->name('api.CustomerRemoveFile'); }); - }) - /* Api for customer */ - ->group(function () { - Route::middleware(['api.auth']) - ->group(function () { - Route::post('get-status-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) { - $vmware_id = $request->vmware_id; - $product_id = $request->product_id; - if (!$vmware_id || !$product_id) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - $product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id); - - if (!$product) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - - if ($vmware_id != $product->vmware_id) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - if ($product->status == 4) { - return response()->json(['error' => false, 'message' => 'Dịch vụ hết hạn', 'expiry' => true]); - } - if ($product->status == 3) { - return response()->json([ - 'error' => false, - 'message' => 'Đang khởi tạo', - 'expiry' => false, - 'pending' => true - ]); - } - - $serviceVCenter->token = $product->ipAddress->host->datacenter->vCenter->token; - $serviceVCenter->apiUri = $product->ipAddress->host->datacenter->vCenter->host; - - $VirtualMachine = $serviceVCenter->CheckVirtualMachine($vmware_id); - - if ($VirtualMachine === 'Login_Again') { - $token = $serviceVCenter->loginServer($product->ipAddress->host->datacenter->vCenter); - if ($token) { - vCenter::where( - 'id', - $product->ipAddress->host->datacenter->vCenter->id - )->update(['token' => $token]); - $serviceVCenter->token = $token; - } - $VirtualMachine = $serviceVCenter->CheckVirtualMachine($vmware_id); - } - - // Check if VirtualMachine is still a string (Login_Again or other error) - if (is_string($VirtualMachine)) { - return response()->json(['error' => true, 'message' => "Failed to check virtual machine: $VirtualMachine"]); - } - - if ($VirtualMachine['error']) { - return response()->json(['error' => true, 'message' => $VirtualMachine['message']]); - } - $status = 3; - if ($VirtualMachine['data']['state'] === 'RUNNING') { - $product->update([ - 'status' => 1 - ]); - } - if ($VirtualMachine['data']['state'] === 'NOT_RUNNING') { - $product->update([ - 'status' => 0 - ]); - } - - $product = ModuleVmware::find($product_id); - - $data = view('form.action')->with([ - 'user' => $request->user('')->id, - 'item' => $product - ])->render(); - return response()->json([ - 'error' => false, - 'message' => $VirtualMachine['data'], - 'expiry' => false, - 'data' => $data - ]); - })->name('api.GetVirtualMachineStatus'); - Route::get('get-list-group-os', function () { - $host_id = \request()->get('host'); - if (!$host_id) { - return response()->json(['error' => true, 'message' => 'Please choose Host']); - } - $host = ModuleHost::find($host_id); - - if (!$host) { - return response()->json(['error' => true, 'message' => 'Can\'t find Host']); - } - - $osGroup = OsGroup::where('ModuleHost_id', $host_id)->select('id', 'name')->get(); - if ($osGroup->count()) { - return response()->json(['error' => false, 'data' => $osGroup->all()]); - } - return response()->json([ - 'error' => true, - 'message' => 'Can\'t find OsGroup by Host ID #' . $host_id - ]); - })->name('api.user.getOsGroup'); - Route::get('get-list-version-os', function () { - $group_id = \request()->get('group'); - if (!$group_id) { - return response()->json(['error' => true, 'message' => 'Please choose Host']); - } - $group_os = OsGroup::find($group_id); - - if (!$group_os) { - return response()->json(['error' => true, 'message' => 'Can\'t find Group Os']); - } - - $os = Os::where('os_group_id', $group_id)->select('id', 'version')->get(); - if ($os->count()) { - $os = array_map(function ($array) { - $array['name'] = $array['version']; - unset($array['version']); - return $array; - }, $os->all()); - return response()->json(['error' => false, 'data' => $os]); - } - return response()->json([ - 'error' => true, - 'message' => 'Can\'t find Os by Os Group ID #' . $group_id - ]); - })->name('api.user.GetVersionOs'); - Route::get('list-snapshot', function () { - $product_id = request()->input('product'); - $user_id = request()->input('user'); - if (!$product_id || !$user_id) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - - $snapshot = ModuleSnapshot::where(function ($query) use ($product_id, $user_id) { - $query->where('customer_id', $user_id); - $query->where('ModuleVmware_id', $product_id); - })->get(); - $data = view('form.snapshot')->with([ - 'snapshot' => $snapshot, - 'user' => $user_id, - 'product' => $product_id - ])->render(); - return response()->json(['error' => false, 'data' => $data]); - })->name('api.user.GetSnapshot'); - Route::get('get-list-addon', function () { - $product = request()->input('product'); - if (!$product) { - return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']); - } - $billing = InvoiceItem::select('billing') - ->where('type_id', 4) - ->where('relid', $product)->first(); - if (!$billing) { - return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']); - } - $allAddon = Addon::get(); - $formAddon = view('form.upgrade')->with([ - 'addon' => $allAddon, - 'billing' => $billing->billing, - 'product' => $product - ])->render(); - - return response()->json(['error' => false, 'data' => $formAddon]); - })->name('api.user.GetAddonProduct'); - Route::post('payment-invoice', function () { - $invoice_id = \request()->input('invoice'); - if (!$invoice_id) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - $invoice = Invoice::with('Order', 'InvoiceItem')->find($invoice_id); - - if (!$invoice) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - if ($invoice->status == 1) { - return response()->json(['error' => true, 'message' => 'Hoá đơn đã được thanh toán!']); - } - $customer = Customer::find(auth()->id()); - - if (!$customer) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - - if ($customer->credit < $invoice->total) { - return response()->json([ - 'error' => true, - 'message' => 'Tài khoản của quý khách không đủ để thực hiện thanh toán' - ]); - } - $products = []; - $next_due_date = 0; - $next_invoice = 0; - if ($invoice->InvoiceItem->count()) { - foreach ($invoice->InvoiceItem->where('relid', '<>', 0) as $item) { - $product = $item->GetRelidProduct(); - $products[] = $product; - $time = $product->next_due_date; - switch ($item->billing) { - case 2: - $next_due_date = Carbon::parse($time)->addMonths(1)->timestamp; - $next_invoice = Carbon::parse($time)->addMonths(1)->timestamp; - break; - case 3: - $next_due_date = Carbon::parse($time)->addMonths(3)->timestamp; - $next_invoice = Carbon::parse($time)->addMonths(3)->timestamp; - break; - case 4: - $next_due_date = Carbon::parse($time)->addMonths(6)->timestamp; - $next_invoice = Carbon::parse($time)->addMonths(6)->timestamp; - break; - case 5: - $next_due_date = Carbon::parse($time)->addMonths(12)->timestamp; - $next_invoice = Carbon::parse($time)->addMonths(12)->timestamp; - break; - } - } - } - try { - DB::beginTransaction(); - $customer->update([ - 'credit' => ($customer->credit - $invoice->total) - ]); - - $invoice->update([ - 'status' => 1, - 'date_paid' => time() - ]); - - $order = $invoice->Order; - $jobs = []; - if ($order && $order->status !== 1 && $invoice->invoice_type == 1) { - $order->update([ - 'status' => 1 - ]); - $addon = []; - $product = 0; - foreach ( - $order->OrderItem->where('parent_id', 0)->whereIn( - 'type_id', - [3, 4] - ) as $key => $item - ) { - if ($item->type_id == 3) { - $Server = ModuleHostingServer::where('status', 1)->first(); - ModuleHosting::find($item->relid)->update(['module_server_id' => $Server->id]); - $jobs[] = new CreateHostingJobs($item->relid); - } else { - $product = $item->GetRelidProduct(); - $os = Os::with('OsGroup')->find($product->os_id); - if ($os && $os->OsGroup) { - $ipaddress = ModuleIpAddress::where( - 'ModuleHost_id', - $os->OsGroup->ModuleHost_id - )->where('status', 0)->first(); - if ($ipaddress) { - $product->update([ - 'ModuleIpAddress_id' => $ipaddress->id - ]); - $ipaddress->update([ - 'status' => 1 - ]); - $jobs[] = new CreateVMJobs($product->id); - } - } - } - } - foreach ($order->OrderItem as $item) { - if ($item->type_id == 1) { - $itemData = $item->GetItemProduct(); - - $price = 0; - - switch ($item->billing) { - case 2: - $price = $item->amount / 1; - break; - case 3: - $price = $item->amount / 3; - break; - case 4: - $price = $item->amount / 6; - break; - case 5: - $price = $item->amount / 12; - break; - } - $addon[strtolower($itemData->name)] = (int) $price / $itemData->price; - $product = $item->parent_id; - } - } - - if ($order->OrderItem->count() === count($addon)) { - dispatch(new UpgradeVirtualMachine( - $product, - $addon, - $order->id - ))->delay(now()->addSeconds(10)); - } - } else { - foreach ($products as $item) { - if (isset($item->vmware_id)) { - $jobs[] = new \App\Jobs\VirtualMachine\Action\VMJobs($item->id, 'Start', true); - } - if (isset($item->server_domain_id)) { - $jobs[] = new \App\Jobs\Hosting\HostingJobs($item->id, 'Activate'); - } - $item->update([ - 'next_due_date' => $next_due_date, - 'next_invoice' => $next_invoice - ]); - } - } - if (count($jobs)) { - foreach ($jobs as $item) { - dispatch($item)->delay(now()->addSeconds(10)); - } - } - DB::commit(); - } catch (Exception $exception) { - DB::rollBack(); - return response()->json(['error' => true, 'message' => $exception->getMessage()]); - } - return response()->json(['error' => false, 'message' => "Thanh toán hoá đơn thành công"]); - })->name('api.user.PaymentInvoice'); - Route::post('renew-services', function () { - $product_id = \request()->input('product'); - $type_id = \request()->input('type'); - $billing = \request()->input('billing'); - if (!$product_id || !$type_id || !$billing) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - $product = null; - - switch ($type_id) { - case 3: - $product = ModuleHosting::find($product_id); - break; - case 4: - $product = ModuleVmware::find($product_id); - break; - } - if (!$product) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - - $customer = Customer::find(auth()->id()); - if (!$customer) { - return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); - } - - $item = InvoiceItem::where(function ($query) use ($product_id, $type_id) { - $query->where('invoice_type', 1); - - $query->where(function ($_query) use ($product_id) { - $_query->where('relid', $product_id); - $_query->Orwhere('parent_id', $product_id); - }); - if ($type_id == 4) { - $query->whereIn('type_id', [1, 4]); - } else { - $query->where('type_id', $type_id); - } - })->get(); - $nextPay = (int) $product->next_payment; - - $renew_item = []; - - if ($item->count()) { - foreach ($item as $key => $_item) { - $renew_item[$key] = $_item->replicate(); - $subMessage = ''; - switch ((int) $billing) { - case 2: - $subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(1)->format('d/m/Y') . " )"; - break; - case 3: - $subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(3)->format('d/m/Y') . " )"; - break; - case 4: - $subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(6)->format('d/m/Y') . " )"; - break; - case 5: - $subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(12)->format('d/m/Y') . " )"; - break; - } - $renew_item[$key]->invoice_type = 0; - $renew_item[$key]->description = $_item->GetItemProduct()->name . $subMessage; - $renew_item[$key]->billing = $billing; - } - } - switch ((int) $billing) { - case 2: - $nextPay *= 1; - break; - case 3: - $nextPay *= 3; - break; - case 4: - $nextPay *= 6; - break; - case 5: - $nextPay *= 12; - break; - } - $date_exp = Carbon::now()->diffInDays(Carbon::parse($product->next_due_date), false); - $invoice_data = [ - 'date' => Carbon::now()->timestamp, - 'due_date' => $date_exp > 0 ? $product->next_due_date : Carbon::now()->timestamp, - 'payment_id' => 1, - 'sub_total' => $nextPay, - 'tax' => $nextPay * (10 / 100), - 'total' => $nextPay + ($nextPay * (10 / 100)), - 'invoice_type' => 0, - 'customer_id' => $product->customer_id, - 'status' => 0 - ]; - try { - DB::beginTransaction(); - $invoice_id = Invoice::insertGetId($invoice_data); - foreach ($renew_item as $item) { - $item->invoice_id = $invoice_id; - $item->save(); - } - DB::commit(); - } catch (Exception $exception) { - DB::rollBack(); - return response()->json(['error' => true, 'message' => $exception->getMessage()]); - } - return response()->json([ - 'error' => false, - 'message' => "Yêu cầu gia hạn được xử lý thành công. Vui lòng thanh toán hoá đơn để hoàn tất!" - ]); - })->name('api.user.RenewService'); - Route::get('get-ticket-console', function (Request $request, ServiceVCenter $serviceVCenter) { - $product_id = $request->get('product'); - if (!$product_id) { - return response()->json(['error' => true, 'message' => "Please choose product"]); - } - $product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id); - if (!$product) { - return response()->json(['error' => true, 'message' => "Can't find product"]); - } - - // Validate that the product belongs to the authenticated user - if ($product->customer_id != user()->id) { - return response()->json([ - 'error' => true, - 'message' => 'Không có quyền truy cập máy ảo này' - ]); - } - - // Check if service is expired - if ($product->status == 4) { - return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']); - } - - // Check if VM is still initializing - if ($product->status == 3) { - return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']); - } - - $vcenter = null; - if ($product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter) { - $vcenter = $product->ipAddress->host->datacenter->vCenter; - } - - if (!$vcenter) { - return response()->json(['error' => true, 'message' => "Can't find vCenter information"]); - } - - // Đăng nhập vCenter trước khi lấy ticket - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ]); - } - - $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); - - // Nếu login hết hạn, thử login lại 1 lần nữa - if ($ConsoleTicket === 'Login_Again') { - if ($serviceVCenter->loginServer($vcenter)) { - $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); - } else { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập lại vào vCenter' - ]); - } - } - - // Nếu vẫn lỗi, trả về lỗi rõ ràng - if (is_string($ConsoleTicket)) { - return response()->json([ - 'error' => true, - 'message' => "Failed to get console ticket: $ConsoleTicket" - ]); - } - - if ($ConsoleTicket['error']) { - return response()->json([ - 'error' => true, - 'message' => $ConsoleTicket['data'] - ]); - } - - return response()->json([ - 'error' => false, - 'data' => $ConsoleTicket['data'], - 'host' => $vcenter->host, - 'vmware-api-session-id' => $serviceVCenter->token - ])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false); - })->name('api.user.GetConsoleTicket'); - - - Route::post('start-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) { - $vm_id = $request->input('vm_id') ?: $request->json('vm_id'); - if (!$vm_id) { - $jsonData = json_decode($request->getContent(), true); - $vm_id = $jsonData['vm_id'] ?? null; - } - - if (!$vm_id) { - return response()->json([ - 'error' => true, - 'message' => 'Yêu cầu không hợp lệ - vm_id không được tìm thấy', - ]); - } - - $vm = ModuleVmware::where('vmware_id', $vm_id)->first(); - - if (!$vm) { - $vm = ModuleVmware::where('id', $vm_id)->first(); - } - - if (!$vm) { - $allVMs = ModuleVmware::where('vmware_id', 'like', '%' . $vm_id . '%') - ->orWhere('id', 'like', '%' . $vm_id . '%') - ->get(); - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin máy ảo', - 'debug' => [ - 'vm_id_received' => $vm_id, - 'similar_vms_count' => $allVMs->count(), - 'similar_vms' => $allVMs->toArray() - ] - ]); - } - - if ($vm->customer_id != user()->id) { - return response()->json([ - 'error' => true, - 'message' => 'Không có quyền truy cập máy ảo này' - ]); - } - - if ($vm->status == 4) { - return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']); - } - - if ($vm->status == 3) { - return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']); - } - - $vcenter = null; - if ($vm->ipAddress && $vm->ipAddress->host && $vm->ipAddress->host->datacenter && $vm->ipAddress->host->datacenter->vCenter) { - $vcenter = $vm->ipAddress->host->datacenter->vCenter; - } - - if (!$vcenter) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin vCenter' - ]); - } - - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ]); - } - - $result = $serviceVCenter->StartVirtualMachine($vm_id); - - if ($result === "Login_Again") { - if ($serviceVCenter->loginServer($vcenter)) { - $result = $serviceVCenter->StartVirtualMachine($vm_id); - } else { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập lại vào vCenter' - ]); - } - } - - // Check if result is still a string (Login_Again or other error) - if (is_string($result)) { - return response()->json(['error' => true, 'message' => "Failed to start virtual machine: $result"]); - } - - if ($result['error']) { - return response()->json(['error' => true, 'message' => $result['data']]); - } - - $vm->update(['status' => 1]); - - return response()->json([ - 'error' => false, - 'message' => 'Khởi động máy ảo thành công' - ]); - })->name('api.user.StartVirtualMachine'); - - Route::post('stop-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) { - $vm_id = $request->input('vm_id') ?: $request->json('vm_id'); - if (!$vm_id) { - $jsonData = json_decode($request->getContent(), true); - $vm_id = $jsonData['vm_id'] ?? null; - } - - if (!$vm_id) { - return response()->json([ - 'error' => true, - 'message' => 'Yêu cầu không hợp lệ - vm_id không được tìm thấy' - ]); - } - - $vm = ModuleVmware::where('vmware_id', $vm_id)->first(); - - if (!$vm) { - $vm = ModuleVmware::where('id', $vm_id)->first(); - } - - if (!$vm) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin máy ảo' - ]); - } - - if ($vm->customer_id != user()->id) { - return response()->json([ - 'error' => true, - 'message' => 'Không có quyền truy cập máy ảo này' - ]); - } - - if ($vm->status == 4) { - return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']); - } - - if ($vm->status == 3) { - return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']); - } - - $vcenter = null; - if ($vm->ipAddress && $vm->ipAddress->host && $vm->ipAddress->host->datacenter && $vm->ipAddress->host->datacenter->vCenter) { - $vcenter = $vm->ipAddress->host->datacenter->vCenter; - } - - if (!$vcenter) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin vCenter' - ]); - } - - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ]); - } - - $result = $serviceVCenter->ShutdownGuestVirtualMachine($vm_id); - - if ($result === "Login_Again") { - if ($serviceVCenter->loginServer($vcenter)) { - $result = $serviceVCenter->ShutdownGuestVirtualMachine($vm_id); - } else { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập lại vào vCenter' - ]); - } - } - - // Check if result is still a string (Login_Again or other error) - if (is_string($result)) { - return response()->json(['error' => true, 'message' => "Failed to stop virtual machine: $result"]); - } - - if ($result['error']) { - return response()->json(['error' => true, 'message' => $result['data']]); - } - - $vm->update(['status' => 0]); - - return response()->json([ - 'error' => false, - 'message' => 'Tắt máy ảo thành công' - ]); - })->name('api.user.StopVirtualMachine'); - - Route::get('get-ip-address', function (Request $request, ServiceVCenter $serviceVCenter) { - try { - $validator = Validator::make($request->all(), [ - 'vm_id' => 'required|string|max:255', - ]); - - if ($validator->fails()) { - return response()->json([ - 'error' => true, - 'message' => 'Dữ liệu không hợp lệ', - 'errors' => $validator->errors() - ], 422); - } - - $vmId = $request->input('vm_id'); - $vm = ModuleVmware::where('vmware_id', $vmId) - ->orWhere('id', $vmId) - ->first(); - - if (!$vm) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin máy ảo' - ], 404); - } - - if ($vm->status == 4) { - return response()->json([ - 'error' => true, - 'message' => 'Dịch vụ đã hết hạn' - ], 400); - } - - if ($vm->status == 3) { - return response()->json([ - 'error' => true, - 'message' => 'Máy ảo đang khởi tạo' - ], 400); - } - - $vcenter = $vm->ipAddress->host->datacenter->vCenter ?? null; - - if (!$vcenter) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin vCenter' - ], 500); - } - - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ], 500); - } - - // Gọi 2 endpoint - $identity = Http::withoutVerifying() - ->withHeaders(['vmware-api-session-id' => $serviceVCenter->token]) - ->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/identity") - ->json(); - - $networking = Http::withoutVerifying() - ->withHeaders(['vmware-api-session-id' => $serviceVCenter->token]) - ->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/networking") - ->json(); - - // Parse IP - $ipAddresses = []; - - // (1) Từ networking - if (isset($networking['value']['interfaces'])) { - foreach ($networking['value']['interfaces'] as $interface) { - foreach ($interface['ip_addresses'] ?? [] as $ip) { - if (isset($ip['ip_address']) && filter_var($ip['ip_address'], FILTER_VALIDATE_IP)) { - $ipAddresses[] = [ - 'ip' => $ip['ip_address'], - 'type' => $ip['type'] ?? 'unknown', - 'state' => $ip['state'] ?? 'unknown', - ]; - } - } - } - } - - // (2) Nếu networking rỗng, fallback từ identity - if (empty($ipAddresses) && isset($identity['value']['ip_address'])) { - $ip = $identity['value']['ip_address']; - if (filter_var($ip, FILTER_VALIDATE_IP)) { - $ipAddresses[] = [ - 'ip' => $ip, - 'type' => strpos($ip, ':') !== false ? 'IPV6' : 'IPV4', - 'state' => 'unknown', - ]; - } - } - - // Update trạng thái - if (!empty($ipAddresses)) { - $vm->update(['status' => 1]); - } - - return response()->json([ - 'error' => false, - 'message' => 'Lấy IP address thành công', - 'data' => [ - 'vm_id' => $vm->vmware_id, - 'hostname' => $vm->hostname, - 'status' => $vm->status, - 'ip_addresses' => $ipAddresses, - 'guest_info' => [ - 'family' => $identity['value']['family'] ?? null, - 'full_name' => $identity['value']['full_name']['default_message'] ?? null, - 'host_name' => $identity['value']['host_name'] ?? null, - ] - ] - ]); - - } catch (\Exception $e) { - Log::error('❌ Lỗi khi lấy IP address của VM', [ - 'vm_id' => $request->input('vm_id'), - 'error' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return response()->json([ - 'error' => true, - 'message' => 'Lỗi hệ thống: ' . $e->getMessage() - ], 500); - } - })->name('api.user.GetIPAddress'); - - Route::get('get-vm-info', function (Request $request, ServiceVCenter $serviceVCenter) { - try { - $validator = Validator::make($request->all(), [ - 'vm_id' => 'required|string|max:255', - ]); - - if ($validator->fails()) { - return response()->json([ - 'error' => true, - 'message' => 'Dữ liệu không hợp lệ', - 'errors' => $validator->errors() - ], 422); - } - - $vmId = $request->input('vm_id'); - - $vcenter = vCenter::first(); - - if (!$vcenter) { - return response()->json([ - 'error' => true, - 'message' => 'Không tìm thấy thông tin vCenter' - ], 500); - } - - // Sử dụng token có sẵn nếu có - $serviceVCenter->apiUri = $vcenter->host; - $serviceVCenter->token = $vcenter->token; - - // Gọi API với timeout 5s - $vmInfo = Http::withoutVerifying() - ->timeout(5) - ->withHeaders(['vmware-api-session-id' => $serviceVCenter->token]) - ->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}") - ->json(); - - // Nếu token hết hạn, login lại 1 lần duy nhất - if (isset($vmInfo['type']) && str_contains($vmInfo['value']['messages'][0]['default_message'] ?? '', 'session')) { - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể đăng nhập vào vCenter' - ], 500); - } - - // Thử lại với token mới - $vmInfo = Http::withoutVerifying() - ->timeout(5) - ->withHeaders(['vmware-api-session-id' => $serviceVCenter->token]) - ->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}") - ->json(); - } - - if (isset($vmInfo['type'])) { - return response()->json([ - 'error' => true, - 'message' => 'Không thể lấy thông tin VM từ vCenter' - ], 500); - } - - return response()->json([ - 'error' => false, - 'message' => 'Lấy thông tin VM thành công', - 'data' => [ - 'vm_id' => $vmId, - 'name' => $vmInfo['value']['name'] ?? 'Unknown', - 'guest_os' => $vmInfo['value']['guest_OS'] ?? 'UNKNOWN', - 'power_state' => $vmInfo['value']['power_state'] ?? 'UNKNOWN', - 'cpu' => [ - 'count' => $vmInfo['value']['cpu']['count'] ?? 0, - 'cores_per_socket' => $vmInfo['value']['cpu']['cores_per_socket'] ?? 0, - 'hot_add_enabled' => $vmInfo['value']['cpu']['hot_add_enabled'] ?? false, - ], - 'memory' => [ - 'size_MiB' => $vmInfo['value']['memory']['size_MiB'] ?? 0, - 'hot_add_enabled' => $vmInfo['value']['memory']['hot_add_enabled'] ?? false, - ], - 'disks' => array_map(function ($disk) { - return [ - 'key' => $disk['key'] ?? '', - 'label' => $disk['value']['label'] ?? '', - 'capacity' => $disk['value']['capacity'] ?? 0, - 'type' => $disk['value']['type'] ?? '', - ]; - }, $vmInfo['value']['disks'] ?? []), - 'nics' => array_map(function ($nic) { - return [ - 'key' => $nic['key'] ?? '', - 'label' => $nic['value']['label'] ?? '', - 'mac_address' => $nic['value']['mac_address'] ?? '', - 'network_name' => $nic['value']['backing']['network_name'] ?? '', - 'state' => $nic['value']['state'] ?? '', - ]; - }, $vmInfo['value']['nics'] ?? []), - 'identity' => [ - 'instance_uuid' => $vmInfo['value']['identity']['instance_uuid'] ?? '', - 'bios_uuid' => $vmInfo['value']['identity']['bios_uuid'] ?? '', - ], - 'hardware' => [ - 'version' => $vmInfo['value']['hardware']['version'] ?? '', - 'upgrade_policy' => $vmInfo['value']['hardware']['upgrade_policy'] ?? '', - ], - 'boot' => [ - 'type' => $vmInfo['value']['boot']['type'] ?? '', - 'efi_legacy_boot' => $vmInfo['value']['boot']['efi_legacy_boot'] ?? false, - ] - ], - 'raw_data' => $vmInfo['value'] ?? null - ]); - - } catch (\Exception $e) { - Log::error('❌ Lỗi khi lấy thông tin VM', [ - 'vm_id' => $request->input('vm_id'), - 'error' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return response()->json([ - 'error' => true, - 'message' => 'Lỗi hệ thống: ' . $e->getMessage() - ], 500); - } - })->name('api.user.GetVMInfo'); - - Route::get('get-vm-info/{vm_id}/{params?}', function (Request $request, ServiceVCenter $serviceVCenter, $vm_id, $params = null) { - try { - $vcenter = vCenter::first(); - - if (!$vcenter) { - return response()->json([ - 'error' => true, - 'message' => __('vCenter configuration not found') - ], 500); - } - - // Login to vCenter first - if (!$serviceVCenter->loginServer($vcenter)) { - return response()->json([ - 'error' => true, - 'message' => __('Cannot login to vCenter') - ], 500); - } - - $vmInfo = $serviceVCenter->GetDetailVirtualMachine($vm_id); - - if ($vmInfo['error']) { - return response()->json([ - 'error' => true, - 'message' => __('Cannot get VM information from vCenter') - ], 500); - } - - $vmData = $vmInfo['data']; - - // Parse các tham số được yêu cầu - $requestedParams = []; - if ($params) { - // Tách các param bằng dấu phẩy hoặc dấu + - $requestedParams = preg_split('/[,+]/', $params); - } - - // Mapping dữ liệu đầy đủ - $allData = [ - 'vm_id' => $vm_id, - 'name' => $vmData['name'] ?? 'Unknown', - 'guest_os' => $vmData['guest_OS'] ?? 'UNKNOWN', - 'power_state' => $vmData['power_state'] ?? 'UNKNOWN', - 'cpu_count' => $vmData['cpu']['count'] ?? 0, - 'cpu_cores_per_socket' => $vmData['cpu']['cores_per_socket'] ?? 0, - 'cpu_hot_add' => $vmData['cpu']['hot_add_enabled'] ?? false, - 'memory_size' => $vmData['memory']['size_MiB'] ?? 0, - 'memory_hot_add' => $vmData['memory']['hot_add_enabled'] ?? false, - 'instance_uuid' => $vmData['identity']['instance_uuid'] ?? '', - 'bios_uuid' => $vmData['identity']['bios_uuid'] ?? '', - 'hardware_version' => $vmData['hardware']['version'] ?? '', - 'boot_type' => $vmData['boot']['type'] ?? '', - 'efi_legacy_boot' => $vmData['boot']['efi_legacy_boot'] ?? false, - ]; - - // Thêm thông tin disk - if (isset($vmData['disks']) && !empty($vmData['disks'])) { - $firstDisk = $vmData['disks'][0] ?? null; - if ($firstDisk) { - $allData['disk_capacity'] = $firstDisk['value']['capacity'] ?? 0; - $allData['disk_label'] = $firstDisk['value']['label'] ?? ''; - $allData['disk_type'] = $firstDisk['value']['type'] ?? ''; - } - } - - // Thêm thông tin network - if (isset($vmData['nics']) && !empty($vmData['nics'])) { - $firstNic = $vmData['nics'][0] ?? null; - if ($firstNic) { - $allData['mac_address'] = $firstNic['value']['mac_address'] ?? ''; - $allData['network_name'] = $firstNic['value']['backing']['network_name'] ?? ''; - $allData['network_state'] = $firstNic['value']['state'] ?? ''; - } - } - - // Nếu không có params cụ thể, trả về tất cả - if (empty($requestedParams)) { - return response()->json([ - 'error' => false, - 'message' => __('Successfully retrieved all VM information'), - 'data' => $allData - ]); - } - - // Lọc chỉ những thông tin được yêu cầu - $filteredData = []; - foreach ($requestedParams as $param) { - $param = trim($param); - if (array_key_exists($param, $allData)) { - $filteredData[$param] = $allData[$param]; - } else { - $filteredData[$param] = null; // Hoặc có thể bỏ qua - } - } - - return response()->json([ - 'error' => false, - 'message' => __('Successfully retrieved VM information'), - 'data' => $filteredData - ]); - - } catch (\Exception $e) { - Log::error('❌ Lỗi khi lấy thông tin VM với params', [ - 'vm_id' => $vm_id, - 'params' => $params, - 'error' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return response()->json([ - 'error' => true, - 'message' => __('System error: :error', ['error' => $e->getMessage()]) - ], 500); - } - })->name('api.user.GetVMInfoWithParams'); - }); }); Route::any('{any}', function () { return response()->json([