From e8656c5655024bd866bd807218a63d7546014118 Mon Sep 17 00:00:00 2001 From: pbao9 Date: Tue, 29 Jul 2025 10:24:14 +0700 Subject: [PATCH] update console --- .../frontend/ServiceController.php | 25 +- .../Invoice/InvoiceCachedRepository.php | 8 +- .../Invoice/InvoiceRepository.php | 4 +- .../Invoice/InvoiceRepositoryInterface.php | 2 +- app/Services/VMHelperService.php | 117 +++++ public/css/service/console.css | 202 ++++++++ .../views/admin/customer/console.blade.php | 110 +--- .../cart/partials/vps-features.blade.php | 4 +- resources/views/frontend/service/README.md | 116 +++++ .../views/frontend/service/console.blade.php | 182 ++----- .../partials/configuration-info.blade.php | 105 ++++ .../control-buttons/console-button.blade.php | 12 + .../control-buttons/renewal-button.blade.php | 13 + .../control-buttons/restart-button.blade.php | 13 + .../control-buttons/snapshot-button.blade.php | 19 + .../control-buttons/start-button.blade.php | 12 + .../control-buttons/stop-button.blade.php | 12 + .../service/partials/control-notes.blade.php | 17 + .../service/partials/no-vm-info.blade.php | 22 + .../service/partials/service-header.blade.php | 29 ++ .../partials/transaction-info.blade.php | 56 ++ .../partials/vm-control-panel.blade.php | 44 ++ .../views/frontend/service/show.blade.php | 489 +----------------- .../livewire/cart/summary-addons.blade.php | 2 +- resources/views/livewire/my-service.blade.php | 5 +- resources/views/welcome.blade.php | 132 ----- routes/web.php | 13 +- 27 files changed, 888 insertions(+), 877 deletions(-) create mode 100644 app/Services/VMHelperService.php create mode 100644 public/css/service/console.css create mode 100644 resources/views/frontend/service/README.md create mode 100644 resources/views/frontend/service/partials/configuration-info.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/console-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/renewal-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/restart-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/snapshot-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/start-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-buttons/stop-button.blade.php create mode 100644 resources/views/frontend/service/partials/control-notes.blade.php create mode 100644 resources/views/frontend/service/partials/no-vm-info.blade.php create mode 100644 resources/views/frontend/service/partials/service-header.blade.php create mode 100644 resources/views/frontend/service/partials/transaction-info.blade.php create mode 100644 resources/views/frontend/service/partials/vm-control-panel.blade.php delete mode 100644 resources/views/welcome.blade.php diff --git a/app/Http/Controllers/frontend/ServiceController.php b/app/Http/Controllers/frontend/ServiceController.php index 6819c17..7c5e334 100644 --- a/app/Http/Controllers/frontend/ServiceController.php +++ b/app/Http/Controllers/frontend/ServiceController.php @@ -28,11 +28,11 @@ class ServiceController extends Controller /** * Hiển thị chi tiết service dựa trên invoice_id - FURTHER OPTIMIZED */ - public function show($invoice_id, vCenter $vCenterService) + public function show($invoice_ordernum, vCenter $vCenterService) { try { // Tìm invoice với các relationship cần thiết - OPTIMIZED - $invoice = $this->invoiceRepository->findWithRelationships($invoice_id, [ + $invoice = $this->invoiceRepository->findWithRelationships($invoice_ordernum, [ 'order', 'invoiceItem.addons', 'invoiceItem.os.osGroup', @@ -334,16 +334,19 @@ class ServiceController extends Controller } - public function vmConsole(Request $request, $invoice_id) + public function vmConsole(Request $request, $invoice_ordernum) { - $cacheKey = 'vm_console_invoice_' . $invoice_id; - $data = cache()->remember($cacheKey, 300, function () use ($invoice_id) { - $invoice = \App\Models\Invoice::where('id', $invoice_id)->first(); - if (!$invoice) return null; - $order = \App\Models\Order::find($invoice->order_id); - if (!$order) return null; - $product = \App\Models\ModuleVmware::where('order_id', $order->id)->first(); - if (!$product) return null; + $cacheKey = 'vm_console_invoice_' . $invoice_ordernum; + $data = cache()->remember($cacheKey, 300, function () use ($invoice_ordernum) { + $invoice = Invoice::where('order_num', $invoice_ordernum)->first(); + if (!$invoice) + return null; + $order = Order::find($invoice->order_id); + if (!$order) + return null; + $product = ModuleVmware::where('order_id', $order->id)->first(); + if (!$product) + return null; $title = "VM Console - " . $product->name; return compact('product', 'title', 'invoice'); }); diff --git a/app/Repositories/Invoice/InvoiceCachedRepository.php b/app/Repositories/Invoice/InvoiceCachedRepository.php index 3672635..a7b9b03 100644 --- a/app/Repositories/Invoice/InvoiceCachedRepository.php +++ b/app/Repositories/Invoice/InvoiceCachedRepository.php @@ -63,18 +63,18 @@ class InvoiceCachedRepository extends BaseCachedRepository implements InvoiceRep return $this->invoiceRepository->get_billing_day($day); }); } - public function findWithRelationships(int $id = 0, array $relationships = [],array $withCount = [], array $withSum = []) + public function findWithRelationships(string $ordernum = '', array $relationships = [], array $withCount = [], array $withSum = []) { $cacheKey = $this->getCacheKey(md5(json_encode([ 'findWithRelationships' => [ - 'id' => $id, + 'ordernum' => $ordernum, 'relationships' => $relationships, 'withCount' => $withCount, 'withSum' => $withSum ] ]))); - return Cache::remember($cacheKey, $this->cacheTime, function () use ($id, $relationships,$withCount,$withSum) { - return $this->invoiceRepository->findWithRelationships($id, $relationships,$withCount,$withSum); + return Cache::remember($cacheKey, $this->cacheTime, function () use ($ordernum, $relationships, $withCount, $withSum) { + return $this->invoiceRepository->findWithRelationships($ordernum, $relationships, $withCount, $withSum); }); } } diff --git a/app/Repositories/Invoice/InvoiceRepository.php b/app/Repositories/Invoice/InvoiceRepository.php index e2cc9a6..425af94 100644 --- a/app/Repositories/Invoice/InvoiceRepository.php +++ b/app/Repositories/Invoice/InvoiceRepository.php @@ -103,7 +103,7 @@ class InvoiceRepository extends BaseRepository implements InvoiceRepositoryInter public function get_billing_day(int|string $day = ''){ return $this->model->whereDate('created_at',$day)->get()->sum('total'); } - public function findWithRelationships(int $id = 0, array $relationships = [], array $withCount = [], array $withSum = []) + public function findWithRelationships(string $ordernum = '', array $relationships = [], array $withCount = [], array $withSum = []) { $model = $this->model; if (count($relationships) > 0) { @@ -148,6 +148,6 @@ class InvoiceRepository extends BaseRepository implements InvoiceRepositoryInter } } - return $model->find($id); + return $model->where('order_num', $ordernum)->first(); } } diff --git a/app/Repositories/Invoice/InvoiceRepositoryInterface.php b/app/Repositories/Invoice/InvoiceRepositoryInterface.php index 1471843..3c2e673 100644 --- a/app/Repositories/Invoice/InvoiceRepositoryInterface.php +++ b/app/Repositories/Invoice/InvoiceRepositoryInterface.php @@ -9,6 +9,6 @@ interface InvoiceRepositoryInterface extends BaseRepositoryInterface{ public function get_billing_year(int $year = 0); public function get_billing_month(int $month = 0); public function get_billing_day(int|string $day = ''); - public function findWithRelationships(int $id = 0, array $relationships = [],array $withCount = [], array $withSum = []); + public function findWithRelationships(string $ordernum = '', array $relationships = [],array $withCount = [], array $withSum = []); } \ No newline at end of file diff --git a/app/Services/VMHelperService.php b/app/Services/VMHelperService.php new file mode 100644 index 0000000..e1ac166 --- /dev/null +++ b/app/Services/VMHelperService.php @@ -0,0 +1,117 @@ + $status, + 'isPoweredOn' => $status === 'POWERED_ON', + 'isPoweredOff' => $status === 'POWERED_OFF', + 'displayStatus' => self::getDisplayStatus($status), + 'statusClass' => self::getStatusClass($status) + ]; + } + + /** + * Get display status text + */ + private static function getDisplayStatus(?string $status): string + { + return match($status) { + 'POWERED_ON' => __('RUNNING'), + 'POWERED_OFF' => __('STOPPED'), + default => __('UNKNOWN') + }; + } + + /** + * Get status CSS class + */ + private static function getStatusClass(?string $status): string + { + return match($status) { + 'POWERED_ON' => 'bg-green-500 text-white', + 'POWERED_OFF' => 'bg-red-500 text-white', + default => 'bg-gray-500 text-white' + }; + } + + /** + * Get VM connection information + */ + public static function getVmConnectionInfo($vmInfo, $invoice): array + { + $isWindows = self::isWindowsOS($vmInfo, $invoice); + + return [ + 'ip' => $vmInfo['ip'] ?? '103.42.56.177', + 'port' => $isWindows ? '3389' : '22', + 'user' => $isWindows ? 'administrator' : 'root', + 'isWindows' => $isWindows + ]; + } + + /** + * Check if OS is Windows + */ + private static function isWindowsOS($vmInfo, $invoice): bool + { + $vmOs = Str::lower($vmInfo['os'] ?? ''); + $invoiceOs = Str::lower($invoice->invoiceItem->first()->os->osGroup->name ?? ''); + + return Str::contains($vmOs, 'windows') || Str::contains($invoiceOs, 'windows'); + } + + /** + * Get VM specifications + */ + public static function getVmSpecs($vmInfo): array + { + return [ + 'cpu' => $vmInfo['cpu'] ?? '3', + 'ram' => $vmInfo['ram'] ?? '1 GB', + 'disk' => $vmInfo['disk'] ?? '25 GB' + ]; + } + + /** + * Format date for display + */ + public static function formatDate($date): string + { + return $date ? Carbon::parse($date)->format('d/m/Y') : 'N/A'; + } + + /** + * Format currency amount + */ + public static function formatCurrency($amount): string + { + return number_format($amount ?? 0, 0, ',', '.') . ' đ'; + } + + /** + * Get service status information + */ + public static function getServiceStatus($invoice): array + { + $isExpired = $invoice->status == 1; + + return [ + 'isExpired' => $isExpired, + 'statusText' => $isExpired ? __('Hết hạn') : __('Hoạt động'), + 'statusClass' => $isExpired ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800' + ]; + } +} \ No newline at end of file diff --git a/public/css/service/console.css b/public/css/service/console.css new file mode 100644 index 0000000..67b17e2 --- /dev/null +++ b/public/css/service/console.css @@ -0,0 +1,202 @@ +/* Admin Console */ + +/* Loading Animation Styles */ +.loading-container { + background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); + min-height: 500px; + position: relative; + overflow: hidden; +} + +.loading-spinner { + width: 60px; + height: 60px; + border: 4px solid rgba(255, 255, 255, 0.2); + border-left: 4px solid #007bff; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +.loading-dots { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.loading-dots span { + width: 8px; + height: 8px; + border-radius: 50%; + background: #007bff; + animation: pulse 1.4s ease-in-out infinite both; +} + +.loading-dots span:nth-child(1) { + animation-delay: -0.32s; +} + +.loading-dots span:nth-child(2) { + animation-delay: -0.16s; +} + +.loading-dots span:nth-child(3) { + animation-delay: 0s; +} + +@keyframes pulse { + 0%, + 80%, + 100% { + transform: scale(0.7); + opacity: 0.5; + } + + 40% { + transform: scale(1); + opacity: 1; + } +} + +.console-container { + transition: all 0.5s ease-in-out; + min-height: 500px; +} + +.fade-transition { + transition: opacity 0.4s ease-in-out; +} + +.spinner-box { + width: 300px; + height: 300px; + display: flex; + justify-content: center; + align-items: center; + background-color: transparent; +} + +.three-quarter-spinner { + width: 50px; + height: 50px; + border: 3px solid #fb5b53; + border-top: 3px solid transparent; + border-radius: 50%; + animation: spin 0.5s linear 0s infinite; +} + +@keyframes spin { + from { + transform: rotate(0); + } + + to { + transform: rotate(359deg); + } +} + + +/* User Console */ +.console-container { + background: #1a1a1a; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.console-header { + background: #2a2a2a; + border-bottom: 1px solid #3a3a3a; + padding: 12px 20px; +} + +.control-panel { + background: white; + border-radius: 8px; + border: 1px solid #e5e7eb; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.btn-primary { + background: #3b82f6; + color: white; + border: none; + padding: 8px 16px; + border-radius: 6px; + font-weight: 500; + transition: background-color 0.2s; +} + +.btn-primary:hover { + background: #2563eb; +} + +.btn-secondary { + background: #f8f9fa; + color: #374151; + border: 1px solid #d1d5db; + padding: 8px 16px; + border-radius: 6px; + font-weight: 500; + transition: all 0.2s; +} + +.btn-secondary:hover { + background: #e5e7eb; +} + +.input-field { + width: 100%; + padding: 8px 12px; + border: 1px solid #d1d5db; + border-radius: 6px; + font-size: 14px; + transition: border-color 0.2s; +} + +.input-field:focus { + outline: none; + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); +} + +.loading-spinner { + width: 32px; + height: 32px; + border: 3px solid #e5e7eb; + border-top: 3px solid #3b82f6; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.section-title { + font-size: 16px; + font-weight: 600; + color: #111827; + margin-bottom: 16px; +} + +.status-dot { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; +} + +.status-connecting { background: #f59e0b; } +.status-connected { background: #10b981; } +.status-error { background: #ef4444; } \ No newline at end of file diff --git a/resources/views/admin/customer/console.blade.php b/resources/views/admin/customer/console.blade.php index efed1ba..b4730bd 100644 --- a/resources/views/admin/customer/console.blade.php +++ b/resources/views/admin/customer/console.blade.php @@ -3,113 +3,7 @@ @push('style') - + @endpush @section('content') @@ -148,7 +42,7 @@