feat: nạp tiền thủ công mã 30 phút, gia hạn trừ số dư, đồng bộ domain từ Plesk

- Nạp tiền: mã thanh toán sống 30 phút (ManualDepositDraft), khôi phục/huỷ mã, lệnh dọn mã hết hạn; total_pending chỉ tính giao dịch đã nộp chứng từ, admin duyệt/từ chối/xoá giao dịch
- Gia hạn dịch vụ: phát hành invoice gia hạn trên order gốc và trừ số dư ngay
- Đồng bộ domain từ Plesk theo server, ServiceOrderRecorder tạo order/invoice cho dịch vụ admin dựng
- Danh sách dịch vụ trả field theo loại (service_plan, dns_records_count), đếm dịch vụ theo loại

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
baodev0
2026-10-11 23:07:51 +07:00
co-authored by Claude Opus 5.5
parent 10af41c5cf
commit c5115b52dd
53 changed files with 1887 additions and 613 deletions
@@ -91,7 +91,7 @@ class ClientController extends Controller
return response()->json([
'error' => false,
'data' => [
'client' => new ClientResource(auth('client')->user()->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource(auth('client')->user()),
],
]);
}
@@ -53,7 +53,7 @@ trait HandlesClientAuthentication
return response()->json([
'error' => false,
'data' => [
'client' => new ClientResource($client->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource($client),
'token' => $result['token'],
'refresh_token' => $result['refresh_token'],
'expires_in' => config('jwt.ttl', 60) * 60, // seconds
@@ -136,7 +136,7 @@ trait HandlesClientAuthentication
return response()->json([
'error' => false,
'data' => [
'client' => new ClientResource($client->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource($client),
'token' => $result['token'],
'refresh_token' => $result['refresh_token'],
'expires_in' => config('jwt.ttl', 60) * 60,
@@ -252,7 +252,7 @@ trait HandlesClientAuthentication
'token' => $result['token'],
'refresh_token' => $result['refresh_token'],
'expires_in' => config('jwt.ttl', 60) * 60,
'client' => new ClientResource($result['client']->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource($result['client']),
],
]);
} catch (\Illuminate\Validation\ValidationException $e) {
@@ -30,7 +30,7 @@ trait ManagesClientProfile
'error' => false,
'message' => 'Cập nhật thông tin thành công',
'data' => [
'client' => new ClientResource($user->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource($user),
],
]);
}
@@ -64,7 +64,7 @@ trait ManagesClientProfile
'error' => false,
'message' => 'Cập nhật chứng minh thư thành công',
'data' => [
'client' => new ClientResource($user->loadCount(['vps', 'hosting', 'domain'])),
'client' => new ClientResource($user),
],
]);
}
@@ -36,6 +36,22 @@ class ServiceController extends Controller
$this->activityLogger = $activityLogger;
}
public function index(Request $request): JsonResponse
{
$customer = $request->user();
$services = $this->serviceClientService->getActiveServices($customer->id, null, null);
$this->serviceClientService->attachDnsRecordCounts($services, $customer->id);
return (new VpsServiceCollection($services))
->additional([
'error' => false,
'message' => 'Lấy dữ liệu thành công',
'page_type' => 'services',
])
->response();
}
public function indexVps(Request $request): JsonResponse
{
$perPage = min((int) $request->get('per_page', 15), 100);
@@ -123,6 +139,7 @@ class ServiceController extends Controller
$customerId = (int) $request->user()->id;
$services = $this->serviceClientService->getActiveServices($customerId, null, 5);
$this->serviceClientService->attachDnsRecordCounts($services, $customerId);
$invoices = $orderQueryService->getCustomerInvoices($customerId)->take(5);
return response()->json([
@@ -131,6 +148,7 @@ class ServiceController extends Controller
'data' => [
'services' => (new VpsServiceCollection($services))->collection,
'invoices' => InvoiceSummaryResource::collection($invoices),
'counts' => $this->serviceClientService->countByType($customerId),
],
]);
}