feat: Implement product duplication, bulk product status updates and deletion, add client service console ticket retrieval, and update service resource to expose server_name.

This commit is contained in:
pbao9
2026-03-13 16:28:23 +07:00
parent e0341363f6
commit 0e5832b1fb
5 changed files with 120 additions and 1 deletions
@@ -161,6 +161,65 @@ class ProductController extends Controller
]);
}
public function duplicate(int $id): JsonResponse
{
$product = Product::with('pricings')->find($id);
if (!$product) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy sản phẩm.'], 404);
}
$copy = $product->replicate(['uuid', 'slug']);
$copy->name = $product->name . ' (Copy)';
$copy->slug = \Illuminate\Support\Str::slug($copy->name) . '-' . time();
$copy->is_active = false;
$copy->save();
// Duplicate pricings
foreach ($product->pricings as $pricing) {
$copy->pricings()->create($pricing->only([
'billing_cycle', 'price', 'renewal_price', 'setup_fee',
]));
}
return response()->json([
'error' => false,
'message' => 'Nhân bản sản phẩm thành công.',
'data' => new ProductResource($copy),
], 201);
}
public function bulkUpdateStatus(Request $request): JsonResponse
{
$validated = $request->validate([
'ids' => 'required|array',
'ids.*' => 'integer',
'is_active' => 'required|boolean',
]);
$updated = Product::whereIn('id', $validated['ids'])
->update(['is_active' => $validated['is_active']]);
$label = $validated['is_active'] ? 'kích hoạt' : 'ẩn';
return response()->json([
'error' => false,
'message' => "Đã {$label} {$updated} sản phẩm.",
]);
}
public function bulkDestroy(Request $request): JsonResponse
{
$ids = $request->validate(['ids' => 'required|array', 'ids.*' => 'integer'])['ids'];
$deleted = Product::whereIn('id', $ids)->delete();
return response()->json([
'error' => false,
'message' => "Đã xoá {$deleted} sản phẩm.",
]);
}
public function getOs(int $id): JsonResponse
{
$product = Product::find($id);
@@ -5,6 +5,8 @@ namespace App\Http\Controllers\Api\Client\Service;
use App\Http\Controllers\Controller;
use App\Http\Resources\Api\Client\Service\ServiceClientDetailResource;
use \App\Http\Resources\Api\Client\Service\ServiceClientResource;
use App\Http\Services\vCenter;
use App\Models\Service;
use App\Repositories\Api\ServiceClient\ServiceClientRepository;
use App\Services\Api\ServiceClient\ServiceClientService;
use Illuminate\Http\Request;
@@ -46,4 +48,59 @@ class ServiceController extends Controller
]);
}
public function getConsoleTicket(Request $request, string $uuid, vCenter $serviceVCenter)
{
$customer = $request->user();
$service = Service::with(['orderItem.order.vmWare.vCenter'])
->where('uuid', $uuid)
->where('customer_id', $customer->id)
->first();
if (!$service) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy dịch vụ'], 404);
}
$vm = $service->orderItem?->order?->vmWare?->first();
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Dịch vụ chưa được cấp phát VM'], 404);
}
$vcenter = $vm->vCenter;
if (!$vcenter) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy thông tin vCenter'], 404);
}
if (!$serviceVCenter->loginServer($vcenter)) {
return response()->json(['error' => true, 'message' => 'Không thể đăng nhập vào vCenter']);
}
$consoleTicket = $serviceVCenter->GetConsoleTickets($vm->vmware_id);
if ($consoleTicket === 'Login_Again') {
if ($serviceVCenter->loginServer($vcenter)) {
$consoleTicket = $serviceVCenter->GetConsoleTickets($vm->vmware_id);
} else {
return response()->json(['error' => true, 'message' => 'Không thể đăng nhập lại vào vCenter']);
}
}
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']]);
}
$ticket = basename(parse_url((string) $consoleTicket['data'], PHP_URL_PATH));
return response()->json([
'error' => false,
'message' => $ticket,
]);
}
}
@@ -20,7 +20,7 @@ class ServiceClientResource extends JsonResource
return [
'uuid' => $this->uuid,
'vm_id' => $this->vm_id,
'server_name' => $this->server_name,
'status' => $this->status,
'auto_renew' => $this->auto_renew,
'started_at' => $this->started_at?->toISOString(),
+2
View File
@@ -97,6 +97,8 @@ Route::prefix('v1')
Route::get('/', 'index')->middleware('perm:product-service.view');
Route::post('/', 'store')->middleware('perm:product-service.create');
Route::post('import', 'import')->middleware('perm:product-service.create');
Route::post('bulk-update-status', 'bulkUpdateStatus')->middleware('perm:product-service.edit');
Route::post('bulk-destroy', 'bulkDestroy')->middleware('perm:product-service.destroy');
Route::controller(ProductController::class)->group(function () {
Route::get('os', 'getOsList')->middleware('perm:product-service.view');
+1
View File
@@ -39,6 +39,7 @@ Route::prefix('v1')->as('api.')->group(function () {
Route::middleware(['api.auth'])->prefix('client-service')->controller(ServiceClientController::class)->as('client-service.')->group(function () {
Route::get('/', 'getService')->name('list');
Route::get('{uuid}', 'getDetail')->name('detail');
Route::get('{uuid}/console-ticket', 'getConsoleTicket')->name('console-ticket');
});