query('product'); if (!$productId) { return response()->json(['error' => true, 'message' => 'Thiếu product id'], 422); } $vm = ModuleVmware::with(['order.orderItems.product.osVersions.osGroup']) ->find($productId); if (!$vm) { return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404); } if ((int) $vm->customer_id !== (int) $request->user()->id) { return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403); } $product = optional($vm->order?->orderItems?->first())->product; if (!$product) { return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404); } $osOptions = $product->osVersions ->where('status', 1) ->map(fn($os) => [ 'id' => $os->id, 'name' => $os->name, 'version' => $os->version, 'group' => $os->osGroup?->name, ]) ->values(); return response()->json([ 'error' => false, 'data' => [ 'product_id' => $product->id, 'product_uuid' => $product->uuid, 'product_name' => $product->name, 'os_options' => $osOptions, ], ]); } public function rebuild(Request $request, vCenter $serviceVCenter): JsonResponse { $customer = $request->user(); $payload = $request->validate([ 'product' => ['required', 'integer'], 'os_id' => ['required', 'integer', 'exists:os,id'], ]); $vm = ModuleVmware::with(['order.orderItems.product', 'vCenter', 'ipAddress.host.datacenter.vCenter']) ->find($payload['product']); if (!$vm) { return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404); } if ((int) $vm->customer_id !== (int) $customer->id) { return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403); } $product = optional($vm->order?->orderItems?->first())->product; if (!$product) { return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404); } $allowedOs = $product->osVersions()->where('status', 1)->pluck('id')->toArray(); if (!in_array((int) $payload['os_id'], array_map('intval', $allowedOs), true)) { return response()->json(['error' => true, 'message' => 'OS không hợp lệ cho product hiện tại'], 422); } DB::table('reinstall_logs')->insert([ 'product_id' => $vm->id, 'product_type' => 4, 'custome_id' => $customer->id, 'os_id' => $payload['os_id'], 'status' => 'pending', 'initiator' => 'client', 'note' => 'Client request rebuild from portal-client', 'created_at' => now(), 'updated_at' => now(), ]); $result = $serviceVCenter->reBuildVPS((string) $vm->name); if (is_string($result) || ($result['error'] ?? false)) { return response()->json([ 'error' => true, 'message' => is_string($result) ? $result : ($result['message'] ?? 'Không thể rebuild VM'), ], 400); } $this->activityLogger->log( event: 'rebuild', logName: 'VM', description: "Customer {$customer->email} rebuild VM: {$vm->name} với OS ID: {$payload['os_id']}", subject: $vm, newValues: ['os_id' => $payload['os_id']], ); return response()->json([ 'error' => false, 'message' => 'Đã gửi yêu cầu rebuild VM', 'data' => $result, ]); } public function addonOptions(Request $request): JsonResponse { $productId = (int) $request->query('product'); if (!$productId) { return response()->json(['error' => true, 'message' => 'Thiếu product id'], 422); } $vm = ModuleVmware::with(['order.orderItems.product.addons']) ->find($productId); if (!$vm) { return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404); } if ((int) $vm->customer_id !== (int) $request->user()->id) { return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403); } $product = optional($vm->order?->orderItems?->first())->product; if (!$product) { return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404); } $addons = $product->addons()->where('status', true)->get()->map(function ($addon) { return [ 'id' => $addon->id, 'code' => strtolower((string) $addon->code), 'name' => $addon->name, 'price' => (float) $addon->price, 'min' => (int) ($addon->min ?? 0), 'max' => (int) ($addon->max ?? 0), 'step' => (int) ($addon->step ?? 1), ]; }); return response()->json([ 'error' => false, 'data' => [ 'product_id' => $product->id, 'product_name' => $product->name, 'base_specs' => [ 'cpu' => (int) ($product->cpu ?? 0), 'ram' => (int) ($product->ram ?? 0), 'disk' => (int) ($product->disk ?? 0), 'bandwidth' => (int) ($product->bandwidth ?? 0), 'gpu' => $product->gpu, ], 'addons' => $addons->values(), ], ]); } public function upgradeAddons(Request $request, vCenter $serviceVCenter): JsonResponse { $customer = $request->user(); $payload = $request->validate([ 'product' => ['required', 'integer'], 'cpu' => ['nullable', 'integer', 'min:0'], 'ram' => ['nullable', 'integer', 'min:0'], 'disk' => ['nullable', 'integer', 'min:0'], 'bandwidth' => ['nullable', 'integer', 'min:0'], 'gpu' => ['nullable', 'string', 'max:255'], ]); $vm = ModuleVmware::with(['vCenter', 'ipAddress.host.datacenter.vCenter']) ->find($payload['product']); if (!$vm) { return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404); } if ((int) $vm->customer_id !== (int) $customer->id) { return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403); } $vcenter = $vm->vCenter ?? $vm->ipAddress?->host?->datacenter?->vCenter; if (!$vcenter || !$serviceVCenter->loginServer($vcenter)) { return response()->json(['error' => true, 'message' => 'Không thể đăng nhập vCenter'], 400); } $applied = []; if (isset($payload['cpu']) && $payload['cpu'] > 0) { $res = $serviceVCenter->UpgradeCPUVirtualMachine($vm->vmware_id, (int) $payload['cpu']); if (is_array($res) && !($res['error'] ?? true)) { $applied[] = 'cpu'; } } if (isset($payload['ram']) && $payload['ram'] > 0) { $res = $serviceVCenter->UpgradeMemoryVirtualMachine($vm->vmware_id, (int) $payload['ram']); if (is_array($res) && !($res['error'] ?? true)) { $applied[] = 'ram'; } } if (isset($payload['disk']) && $payload['disk'] > 0) { $res = $serviceVCenter->UpgradeDiskVirtualMachine($vm, (int) $payload['disk']); if (is_array($res) && !($res['error'] ?? true)) { $applied[] = 'disk'; } } $this->activityLogger->log( event: 'upgrade_addons', logName: 'VM', description: "Customer {$customer->email} nâng cấp addons VM: {$vm->name} - áp dụng: " . implode(', ', $applied ?: ['none']), subject: $vm, newValues: array_filter(['cpu' => $payload['cpu'] ?? null, 'ram' => $payload['ram'] ?? null, 'disk' => $payload['disk'] ?? null]), ); return response()->json([ 'error' => false, 'message' => 'Đã gửi yêu cầu nâng cấp addons', 'data' => [ 'applied' => $applied, 'note' => 'bandwidth/gpu hiện được ghi nhận yêu cầu, chưa có luồng tự động áp vào VM', ], ]); } }