feat(service): huỷ dịch vụ, SSL, đổi mật khẩu hosting, lịch sử thanh toán theo hình thức

- Lịch sử thanh toán hoá đơn trả thêm `method` (tự động gia hạn / số dư / admin / chuyển khoản / hoàn tiền), bỏ đuôi `(method)` khỏi ghi chú
- `DnsServer::panelUrl()` = https://<domain>/ dùng cho email cấp hosting và nút Plesk của khách
- Order item trả thêm `uuid`/`type` của dịch vụ để FE dẫn tới trang quản lý
- Yêu cầu huỷ dịch vụ, chứng chỉ SSL, lịch sử gia hạn, đổi mật khẩu hosting cho khách

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
baodev0
2026-10-28 16:40:24 +07:00
co-authored by Claude Sonnet 5.5
parent a6b641015e
commit b44a88bb52
72 changed files with 1701 additions and 231 deletions
@@ -84,6 +84,21 @@ class ServiceController extends Controller
->response();
}
public function indexGroup(Request $request, string $group): JsonResponse
{
$perPage = min((int) $request->get('per_page', 15), 100);
$services = $this->serviceClientService->getActiveServices($request->user()->id, null, $perPage, $group);
return (new VpsServiceCollection($services))
->additional([
'error' => false,
'message' => 'Lấy dữ liệu thành công',
'page_type' => 'service_' . $group,
])
->response();
}
public function indexDomain(Request $request): JsonResponse
{
$customerId = $request->user()->id;
@@ -102,11 +117,12 @@ class ServiceController extends Controller
->where('customer_id', $customerId)
->where('type', 'domain')
->orderByDesc('id')
->get(['uuid', 'server_name', 'status', 'started_at', 'expires_at'])
->get(['uuid', 'server_name', 'status', 'started_at', 'expires_at', 'cancel_at_expiry'])
->map(fn (Service $service) => [
'domain_name' => $service->server_name,
'service_uuid' => $service->uuid,
'status' => $service->status,
'cancel_at_expiry' => (bool) $service->cancel_at_expiry,
'started_at' => $service->started_at?->toISOString(),
'expires_at' => $service->expires_at?->toISOString(),
...$zoneFields($zones->pull(mb_strtolower(trim((string) $service->server_name)))),
@@ -194,20 +210,16 @@ class ServiceController extends Controller
]);
}
public function getVmPassword(Request $request, string $uuid)
public function downloadAttachment(Request $request, string $uuid, int $attachmentId)
{
$service = Service::with('vmware')
->where('uuid', $uuid)
->where('customer_id', $request->user()->id)
->first();
$attachment = \App\Models\ServiceAttachment::forCustomer()
->whereKey($attachmentId)
->whereHas('service', fn ($query) => $query
->where('uuid', $uuid)
->where('customer_id', $request->user()->id))
->firstOrFail();
$vm = $service?->vmware;
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy dịch vụ'], 404);
}
return response()->json(['error' => false, 'data' => ['password' => $vm->plain_password]]);
return \Illuminate\Support\Facades\Storage::disk($attachment->disk)->response($attachment->path, $attachment->filename);
}
public function getConsoleTicket(Request $request, string $uuid, vCenter $serviceVCenter)