diff --git a/config/sidebar.php b/config/sidebar.php index 37265c6..e2f382a 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -46,9 +46,9 @@ return [ 'icon' => 'fas fa-map-marker-alt', ], [ - 'title' => 'Location', - 'route' => 'package.datastore.index', - 'icon' => 'fas fa-hdd', + 'title' => 'Virtual Machines', + 'route' => 'package.vm.index', + 'icon' => 'fas fa-server', ], ], ], diff --git a/database/migrations/2026_01_29_120313_create_virtual_machines_table.php b/database/migrations/2026_01_29_120313_create_virtual_machines_table.php index 78a3f5a..c207ce7 100644 --- a/database/migrations/2026_01_29_120313_create_virtual_machines_table.php +++ b/database/migrations/2026_01_29_120313_create_virtual_machines_table.php @@ -16,14 +16,17 @@ return new class extends Migration { $table->string('vm_id')->unique(); $table->string('name'); + $table->string('power_state')->nullable(); + $table->string('folder')->nullable(); $table->boolean('is_template')->default(false); // Specs snapshot $table->integer('cpu')->nullable(); $table->integer('ram_mb')->nullable(); - $table->integer('disk_gb')->nullable(); // Mapping + $table->boolean('is_system')->default(false); // vCLS, system VM + $table->timestamp('last_synced_at')->nullable(); $table->foreignId('datacenter_id')->constrained('module_datacenter')->nullable(); - $table->foreignId('host_id')->nullable(); + $table->foreignId('host_id')->constrained('module_host')->nullable(); $table->timestamps(); }); } diff --git a/database/migrations/2026_01_29_120327_create_product_v_m_templates_table.php b/database/migrations/2026_01_29_120327_create_product_v_m_templates_table.php index d800154..2e0fabf 100644 --- a/database/migrations/2026_01_29_120327_create_product_v_m_templates_table.php +++ b/database/migrations/2026_01_29_120327_create_product_v_m_templates_table.php @@ -11,9 +11,9 @@ return new class extends Migration */ public function up(): void { - Schema::create('product_v_m_templates', function (Blueprint $table) { - $table->id(); - $table->timestamps(); + Schema::create('product_vm_templates', function (Blueprint $table) { + $table->foreignId('product_id')->constrained('products')->cascadeOnDelete(); + $table->foreignId('vm_template_id')->constrained('vm_templates')->cascadeOnDelete(); }); } @@ -22,6 +22,6 @@ return new class extends Migration */ public function down(): void { - Schema::dropIfExists('product_v_m_templates'); + Schema::dropIfExists('product_vm_templates'); } }; diff --git a/routes/customer.php b/routes/customer.php new file mode 100644 index 0000000..f7f5e7d --- /dev/null +++ b/routes/customer.php @@ -0,0 +1,136 @@ +controller(ClientController::class) + ->group(function () { + Route::get('dang-nhap', 'Login')->name('user.login'); + Route::post('dang-nhap', 'LoginStore')->name("user.login.store"); + Route::get('quen-mat-khau', 'Reset')->name('user.reset'); + Route::post('quen-mat-khau', 'ResetStore')->name('user.reset.store'); + Route::get('dang-ky-tai-khoan', 'Register')->name('user.register'); + Route::post('dang-ky-tai-khoan', 'RegisterStore')->name('user.register.store'); + Route::get('xac-thuc-tai-khoan', 'Verify')->name('user.verify'); + Route::post('cap-nhat-thong-bao', 'updateNotification')->name('user.updateNotification'); + }); + +Route::middleware("CustomerLoginCheck")->group(function () { + + // Route::get('/trang-chu', [MainController::class, 'index'])->name("home_old"); + Route::get('/', [MainController::class, 'index_new'])->name('home'); + + + Route::get('nhat-ky-hoat-dong', [CustomerLogController::class, 'index'])->name('frontend.customer.log'); + Route::controller(ClientController::class)->group(function () { + Route::get('dang-xuat', 'Logout')->name("user.logout"); + Route::get('thong-tin-tai-khoan', 'Information')->name('user.information'); + Route::put('thong-tin-tai-khoan', 'StoreInformation')->name('user.information.store'); + Route::get('lich-su-email', 'Email')->name('user.email'); + Route::get('chi-tiet-email', 'ViewEmail')->name('user.email.view'); + Route::get('doi-mat-khau', 'ChangePassword')->name('user.password'); + Route::put('doi-mat-khau', 'StoreChangePassword')->name('user.password.store'); + }); + Route::controller(TicketController::class)->group(function () { + Route::get('danh-sach-yeu-cau-support', 'index')->name('ticket'); + Route::get('gui-yeu-cau-support', 'create')->name('ticket.create'); + Route::post('gui-yeu-cau-support', 'store')->name('ticket.store'); + Route::get('xem-yeu-cau-support', 'show')->name('ticket.show'); + Route::post('reply-yeu-cau-support', 'ReplyStore')->name('ticket.reply.store'); + Route::put('dong-yeu-cau-support', 'ClosedTicket')->name('ticket.closed'); + }); + Route::controller(CustomerInvoice::class)->group(function () { + Route::post('thanh-toan-hoa-don/{order_id}/{order_num}', 'store')->name('client.invoice.store'); + Route::get('danh-sach-hoa-don', 'index')->name('invoice.index'); + Route::get('chi-tiet-hoa-don/{invoice_id}/{order_num}', 'show')->name('invoice.show'); + }); + Route::controller(ShopController::class)->group(function () { + Route::get('danh-sach-dich-vu', 'index')->name('shop'); + Route::get('dich-vu/{slug}', 'show')->name('shop.show'); + Route::get('product/{slug}', 'getProduct')->name('shop.product'); + Route::post('them-vao-gio-hang', 'store')->name('shop.store'); + }); + + Route::controller(ClientOrderController::class)->group(function () { + Route::post('them-order', 'store')->name('client.order.store'); + Route::get('don-hang/{order_id}/thanh-toan', 'payment')->name('client.order.payment'); + Route::delete('don-hang/{order_id}', 'destroy')->name('client.order.destroy'); + + Route::get('danh-sach-don-hang', 'index')->name('order.index'); + }); + + + + Route::controller(CartController::class)->group(function () { + Route::post('them-gio-hang', 'addCart')->name('cart.add'); + Route::get('gio-hang', 'index')->name('cart.index'); + Route::post('gio-hang', 'order')->name('cart.store'); + Route::post('add-coupon', 'applyCoupon')->name('cart.applyCoupon'); + Route::get('remove-item-gio-hang', 'destroy')->name('cart.remove'); + Route::post('order-addon', 'addon')->name('cart.addon'); + }); + Route::controller(ManagerService::class)->group(function () { + Route::get('dich-vu-cua-toi', 'index')->name('service.index'); + Route::get('chi-tiet-dich-vu', 'show')->name('service.show'); + Route::post('reinstall-vmware', 'reinstall')->name('service.reinstall'); + Route::post('task-action', 'action')->name('service.action'); + Route::post('task-snapshot', 'snapshot')->name('service.snapshot'); + Route::get('view-console', 'console')->name('service.console'); + }); + + // Service Controller routes + Route::prefix('dich-vu-dang-ky')->controller(ServiceController::class)->group(function () { + Route::get('{invoice_ordernum}', 'show')->name('service.detail'); + Route::post('{invoice_ordernum}/vm/toggle', 'toggleVM')->name('service.vm.toggle'); + Route::get('{invoice_ordernum}/vm/info', 'getVMInfo')->name('service.vm.info'); + Route::get('{invoice_ordernum}/vmware-demo', 'vmwareDemo')->name('service.vmware.demo'); + Route::get('{invoice_ordernum}/vm-console', 'vmConsole')->name('service.vm.console'); + + Route::post('secure/create-snapshots', 'createSnapshots')->name('service.create.snapshots'); + Route::get('secure/get-snapshots', 'getSnapshots')->name('service.get.snapshots'); + Route::post('secure/remove-snapshot', 'removeSnapshot')->name('service.remove.snapshot'); + Route::post('secure/revert-snapshot', 'revertSnapshot')->name('service.revert.snapshot'); + Route::post('secure/reinstall-vm', 'reinstallVM')->name('service.reinstall.vm'); + Route::post('secure/reset-vm-password', 'resetVMPassword')->name('service.reset.vm.password'); + Route::post('secure/change-remote-port', 'changeRemotePort')->name('service.change.remote.port'); + Route::post('secure/change-ip', 'changeIP')->name('service.change.ip'); + Route::post('secure/renew-price', 'renewPrice')->name('service.renew.price'); + Route::post('secure/renew', 'renew')->name('service.renew'); + Route::post('secure/start-vm', 'startVM')->name('service.start.vm'); + Route::post('secure/stop-vm', 'stopVM')->name('service.stop.vm'); + Route::post('secure/reboot-vm', 'rebootVM')->name('service.reboot.vm'); + }); + + Route::controller(CustomerDomainController::class)->group(function () { + Route::get('danh-sach-ten-mien', 'index')->name('customer.domain.index'); + }); + Route::controller(RechargeController::class)->group(function () { + Route::get('nap-tien', 'index')->name('recharge.index'); + Route::post('nap-tien', 'paymentProcess')->name('recharge.paymentProcess.vnPay'); + Route::get('nap-tien/return', 'paymentReturn')->name('recharge.return'); + Route::get('thanh-toan', 'show')->name('recharge.show'); + Route::get('lich-su-giao-dich', 'HistoryRecharge')->name('recharge.history'); + Route::get('callback-function', 'CallbackResponse')->name('recharge.CallbackResponse'); + }); + Route::controller(CustomerPostController::class)->group(function () { + Route::get('tin-tuc/{slug}', 'view')->name('post'); + }); + + Route::controller(\App\Http\Controllers\frontend\Whois\WhoisController::class)->group(function () { + Route::get('kiem-tra-ten-mien', 'index')->name('whois.index'); + Route::post('api/whois/domain-info', 'getDomainInfo')->name('whois.domain-info'); + Route::post('api/whois/check-availability', 'checkAvailability')->name('whois.check-availability'); + }); +}); diff --git a/routes/web.php b/routes/web.php index b4c426e..fef2c3c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -34,19 +34,6 @@ use App\Http\Controllers\admin\SupportController; use App\Http\Controllers\admin\TaskController; use App\Http\Controllers\admin\TemplateController; use App\Http\Controllers\admin\UserController; -use App\Http\Controllers\frontend\CartController; -use App\Http\Controllers\frontend\CustomerLogController; -use App\Http\Controllers\frontend\DomainController as CustomerDomainController; -use App\Http\Controllers\frontend\InvoiceController as CustomerInvoice; -use App\Http\Controllers\frontend\MainController; -use App\Http\Controllers\frontend\ManagerService; -use App\Http\Controllers\frontend\PostController as CustomerPostController; -use App\Http\Controllers\frontend\RechargeController; -use App\Http\Controllers\frontend\ServiceController; -use App\Http\Controllers\frontend\ShopController; -use App\Http\Controllers\frontend\TicketController; -use App\Http\Controllers\frontend\UserController as ClientController; -use App\Http\Controllers\frontend\Order\OrderController as ClientOrderController; use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; @@ -428,123 +415,5 @@ Route::prefix('administrator')->group(function () { }); }); -Route::middleware("IsLoginCheck") - ->controller(ClientController::class) - ->group(function () { - Route::get('dang-nhap', 'Login')->name('user.login'); - Route::post('dang-nhap', 'LoginStore')->name("user.login.store"); - Route::get('quen-mat-khau', 'Reset')->name('user.reset'); - Route::post('quen-mat-khau', 'ResetStore')->name('user.reset.store'); - Route::get('dang-ky-tai-khoan', 'Register')->name('user.register'); - Route::post('dang-ky-tai-khoan', 'RegisterStore')->name('user.register.store'); - Route::get('xac-thuc-tai-khoan', 'Verify')->name('user.verify'); - Route::post('cap-nhat-thong-bao', 'updateNotification')->name('user.updateNotification'); - }); -Route::middleware("CustomerLoginCheck")->group(function () { - - // Route::get('/trang-chu', [MainController::class, 'index'])->name("home_old"); - Route::get('/', [MainController::class, 'index_new'])->name('home'); - - - Route::get('nhat-ky-hoat-dong', [CustomerLogController::class, 'index'])->name('frontend.customer.log'); - Route::controller(ClientController::class)->group(function () { - Route::get('dang-xuat', 'Logout')->name("user.logout"); - Route::get('thong-tin-tai-khoan', 'Information')->name('user.information'); - Route::put('thong-tin-tai-khoan', 'StoreInformation')->name('user.information.store'); - Route::get('lich-su-email', 'Email')->name('user.email'); - Route::get('chi-tiet-email', 'ViewEmail')->name('user.email.view'); - Route::get('doi-mat-khau', 'ChangePassword')->name('user.password'); - Route::put('doi-mat-khau', 'StoreChangePassword')->name('user.password.store'); - }); - Route::controller(TicketController::class)->group(function () { - Route::get('danh-sach-yeu-cau-support', 'index')->name('ticket'); - Route::get('gui-yeu-cau-support', 'create')->name('ticket.create'); - Route::post('gui-yeu-cau-support', 'store')->name('ticket.store'); - Route::get('xem-yeu-cau-support', 'show')->name('ticket.show'); - Route::post('reply-yeu-cau-support', 'ReplyStore')->name('ticket.reply.store'); - Route::put('dong-yeu-cau-support', 'ClosedTicket')->name('ticket.closed'); - }); - Route::controller(CustomerInvoice::class)->group(function () { - Route::post('thanh-toan-hoa-don/{order_id}/{order_num}', 'store')->name('client.invoice.store'); - Route::get('danh-sach-hoa-don', 'index')->name('invoice.index'); - Route::get('chi-tiet-hoa-don/{invoice_id}/{order_num}', 'show')->name('invoice.show'); - }); - Route::controller(ShopController::class)->group(function () { - Route::get('danh-sach-dich-vu', 'index')->name('shop'); - Route::get('dich-vu/{slug}', 'show')->name('shop.show'); - Route::get('product/{slug}', 'getProduct')->name('shop.product'); - Route::post('them-vao-gio-hang', 'store')->name('shop.store'); - }); - - Route::controller(ClientOrderController::class)->group(function () { - Route::post('them-order', 'store')->name('client.order.store'); - Route::get('don-hang/{order_id}/thanh-toan', 'payment')->name('client.order.payment'); - Route::delete('don-hang/{order_id}', 'destroy')->name('client.order.destroy'); - - Route::get('danh-sach-don-hang', 'index')->name('order.index'); - }); - - - - Route::controller(CartController::class)->group(function () { - Route::post('them-gio-hang', 'addCart')->name('cart.add'); - Route::get('gio-hang', 'index')->name('cart.index'); - Route::post('gio-hang', 'order')->name('cart.store'); - Route::post('add-coupon', 'applyCoupon')->name('cart.applyCoupon'); - Route::get('remove-item-gio-hang', 'destroy')->name('cart.remove'); - Route::post('order-addon', 'addon')->name('cart.addon'); - }); - Route::controller(ManagerService::class)->group(function () { - Route::get('dich-vu-cua-toi', 'index')->name('service.index'); - Route::get('chi-tiet-dich-vu', 'show')->name('service.show'); - Route::post('reinstall-vmware', 'reinstall')->name('service.reinstall'); - Route::post('task-action', 'action')->name('service.action'); - Route::post('task-snapshot', 'snapshot')->name('service.snapshot'); - Route::get('view-console', 'console')->name('service.console'); - }); - - // Service Controller routes - Route::prefix('dich-vu-dang-ky')->controller(ServiceController::class)->group(function () { - Route::get('{invoice_ordernum}', 'show')->name('service.detail'); - Route::post('{invoice_ordernum}/vm/toggle', 'toggleVM')->name('service.vm.toggle'); - Route::get('{invoice_ordernum}/vm/info', 'getVMInfo')->name('service.vm.info'); - Route::get('{invoice_ordernum}/vmware-demo', 'vmwareDemo')->name('service.vmware.demo'); - Route::get('{invoice_ordernum}/vm-console', 'vmConsole')->name('service.vm.console'); - - Route::post('secure/create-snapshots', 'createSnapshots')->name('service.create.snapshots'); - Route::get('secure/get-snapshots', 'getSnapshots')->name('service.get.snapshots'); - Route::post('secure/remove-snapshot', 'removeSnapshot')->name('service.remove.snapshot'); - Route::post('secure/revert-snapshot', 'revertSnapshot')->name('service.revert.snapshot'); - Route::post('secure/reinstall-vm', 'reinstallVM')->name('service.reinstall.vm'); - Route::post('secure/reset-vm-password', 'resetVMPassword')->name('service.reset.vm.password'); - Route::post('secure/change-remote-port', 'changeRemotePort')->name('service.change.remote.port'); - Route::post('secure/change-ip', 'changeIP')->name('service.change.ip'); - Route::post('secure/renew-price', 'renewPrice')->name('service.renew.price'); - Route::post('secure/renew', 'renew')->name('service.renew'); - Route::post('secure/start-vm', 'startVM')->name('service.start.vm'); - Route::post('secure/stop-vm', 'stopVM')->name('service.stop.vm'); - Route::post('secure/reboot-vm', 'rebootVM')->name('service.reboot.vm'); - }); - - Route::controller(CustomerDomainController::class)->group(function () { - Route::get('danh-sach-ten-mien', 'index')->name('customer.domain.index'); - }); - Route::controller(RechargeController::class)->group(function () { - Route::get('nap-tien', 'index')->name('recharge.index'); - Route::post('nap-tien', 'paymentProcess')->name('recharge.paymentProcess.vnPay'); - Route::get('nap-tien/return', 'paymentReturn')->name('recharge.return'); - Route::get('thanh-toan', 'show')->name('recharge.show'); - Route::get('lich-su-giao-dich', 'HistoryRecharge')->name('recharge.history'); - Route::get('callback-function', 'CallbackResponse')->name('recharge.CallbackResponse'); - }); - Route::controller(CustomerPostController::class)->group(function () { - Route::get('tin-tuc/{slug}', 'view')->name('post'); - }); - - Route::controller(\App\Http\Controllers\frontend\Whois\WhoisController::class)->group(function () { - Route::get('kiem-tra-ten-mien', 'index')->name('whois.index'); - Route::post('api/whois/domain-info', 'getDomainInfo')->name('whois.domain-info'); - Route::post('api/whois/check-availability', 'checkAvailability')->name('whois.check-availability'); - }); -}); +include __DIR__ . '/customer.php';