Files
portal-api/app/Http/Controllers/Api/Admin/IpPool/Concerns/ManagesIpPoolBulkActions.php
T
2026-09-28 08:26:29 +07:00

183 lines
6.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\IpPool\Concerns;
use App\Imports\IpPoolImport;
use App\Models\IpPool;
use App\Models\ModuleIpAddress;
use App\Models\ModuleNetwork;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
use Maatwebsite\Excel\Validators\ValidationException;
trait ManagesIpPoolBulkActions
{
public function bulkUpdateGateway(Request $request): JsonResponse
{
$request->validate([
'ids' => 'required|array|min:1',
'ids.*' => 'integer',
'gateway' => 'required|string|max:45',
]);
$pools = IpPool::whereIn('id', $request->ids)->get(['id', 'ip_address', 'module_network_id']);
if ($pools->isEmpty()) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy IP Pool nào'], 404);
}
DB::beginTransaction();
try {
IpPool::whereIn('id', $pools->pluck('id'))->update(['gateway' => $request->gateway]);
// Mirror into module_ip_address, grouped by network to keep this to a handful of queries.
foreach ($pools->groupBy('module_network_id') as $networkId => $group) {
ModuleIpAddress::whereIn('ip', $group->pluck('ip_address'))
->where('module_network_id', $networkId)
->update(['gateway' => $request->gateway]);
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
return response()->json(['error' => true, 'message' => $e->getMessage()], 500);
}
return response()->json([
'error' => false,
'message' => "Đã cập nhật gateway cho {$pools->count()} IP",
'updated' => $pools->count(),
]);
}
public function bulkDelete(Request $request): JsonResponse
{
$request->validate([
'ids' => 'required|array|min:1',
'ids.*' => 'integer',
]);
$ids = $request->ids;
$pools = IpPool::whereIn('id', $ids)->get();
if ($pools->isEmpty()) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy IP Pool nào'], 404);
}
// Block deletion if any IP is currently assigned
$inUseIps = ModuleIpAddress::whereIn('ip', $pools->pluck('ip_address'))
->where('status', 1)
->pluck('ip')
->toArray();
if (!empty($inUseIps)) {
return response()->json([
'error' => true,
'message' => 'Không thể xoá — các IP sau đang được gán cho máy chủ: ' . implode(', ', $inUseIps),
], 422);
}
foreach ($pools as $p) {
ModuleIpAddress::where('ip', $p->ip_address)
->where('module_network_id', $p->module_network_id)
->delete();
}
$deleted = IpPool::whereIn('id', $ids)->delete();
return response()->json([
'error' => false,
'message' => "Đã xoá {$deleted} IP Pool thành công",
'deleted' => $deleted,
]);
}
public function import(Request $request): JsonResponse
{
$request->validate([
'file' => 'required|file|mimes:csv,txt|max:10240',
]);
$countBefore = IpPool::withTrashed()->count();
try {
Excel::import(new IpPoolImport(), $request->file('file'));
} catch (ValidationException $e) {
$errors = [];
foreach ($e->failures() as $failure) {
$errors[] = 'Dòng ' . $failure->row() . ': ' . implode(', ', $failure->errors());
}
return response()->json([
'error' => true,
'message' => 'Import thất bại',
'errors' => $errors,
], 422);
} catch (\Exception $e) {
return response()->json(['error' => true, 'message' => 'Import thất bại: ' . $e->getMessage()], 500);
}
$countAfter = IpPool::withTrashed()->count();
IpPool::resyncAllContacts();
return response()->json([
'error' => false,
'message' => 'Import thành công',
'created' => max(0, $countAfter - $countBefore),
]);
}
/**
* Backfill/repair the module_ip_address mirror for every ip_pools row.
* Existing mirror rows only get gateway/netmask refreshed — status/vm_name
* (assigned VM state) is left untouched. Missing rows are created with
* status derived from the current ip_pools.status.
*/
public function sync(): JsonResponse
{
$created = 0;
$updated = 0;
$hostByNet = ModuleNetwork::pluck('module_host_id', 'id');
IpPool::chunkById(500, function ($pools) use (&$created, &$updated, $hostByNet) {
foreach ($pools as $pool) {
$hostId = $hostByNet[$pool->module_network_id] ?? null;
$netmask = $pool->netmask ?: '255.255.255.0';
$mia = ModuleIpAddress::where('ip', $pool->ip_address)
->where('module_network_id', $pool->module_network_id)
->first();
if ($mia) {
$mia->update([
'module_host_id' => $hostId,
'gateway' => $pool->gateway,
'netmask' => $netmask,
]);
$updated++;
} else {
ModuleIpAddress::create([
'ip' => $pool->ip_address,
'module_network_id' => $pool->module_network_id,
'module_host_id' => $hostId,
'gateway' => $pool->gateway,
'netmask' => $netmask,
'status' => $pool->status === 'assigned' ? 1 : 0,
]);
$created++;
}
}
});
return response()->json([
'error' => false,
'message' => "Đã đồng bộ: tạo mới {$created}, cập nhật {$updated}",
'created' => $created,
'updated' => $updated,
]);
}
}