Files
portal-api/app/Services/Api/ServiceClient/ServiceClientService.php
T
baodev0andClaude Sonnet 5.5 b44a88bb52 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>
2026-10-28 16:40:24 +07:00

95 lines
3.2 KiB
PHP

<?php
namespace App\Services\Api\ServiceClient;
use App\Models\DnsDomain;
use App\Models\Service;
use App\Repositories\Api\ServiceClient\ServiceClientRepositoryInterface;
class ServiceClientService
{
protected $serviceClientRepository;
public function __construct(ServiceClientRepositoryInterface $serviceClientRepository)
{
$this->serviceClientRepository = $serviceClientRepository;
}
/**
* Lấy danh sách dịch vụ đang hoạt động
*/
public function getActiveServices(int $customerId, ?string $productType = null, ?int $limit = 10, ?string $group = null)
{
return $this->serviceClientRepository->getActiveServices($customerId, $productType, $limit, $group);
}
/**
* @return array{vps: int, server: int, hosting: int, domain: int}
*/
public function countByType(int $customerId): array
{
$counts = Service::query()
->where('customer_id', $customerId)
->whereNotIn('status', ['cancelled', 'terminated'])
->selectRaw('type, COUNT(*) as total')
->groupBy('type')
->pluck('total', 'type');
return [
'vps' => (int) $counts->get('vps', 0),
'server' => (int) $counts->get('server', 0),
'hosting' => (int) $counts->get('hosting', 0),
'domain' => (int) $counts->get('domain', 0) + $this->countZonesWithoutService($customerId),
];
}
private function countZonesWithoutService(int $customerId): int
{
$serviceDomains = Service::query()
->where('customer_id', $customerId)
->where('type', 'domain')
->whereNotIn('status', ['cancelled', 'terminated'])
->pluck('server_name')
->map(fn ($name) => mb_strtolower(trim((string) $name)));
return DnsDomain::query()
->whereHas('customer', fn ($query) => $query->where('customers.id', $customerId))
->where('is_created', '!=', DnsDomain::STATUS_CANCELLED)
->pluck('domain_name')
->map(fn ($name) => mb_strtolower(trim((string) $name)))
->unique()
->diff($serviceDomains)
->count();
}
/**
* @param iterable<Service> $services
*/
public function attachDnsRecordCounts(iterable $services, int $customerId): void
{
$counts = DnsDomain::query()
->withCount('ns')
->whereHas('customer', fn ($query) => $query->where('customers.id', $customerId))
->get(['id', 'domain_name'])
->mapWithKeys(fn (DnsDomain $domain) => [
mb_strtolower(trim($domain->domain_name)) => (int) $domain->ns_count,
]);
foreach ($services as $service) {
if ($service->type === 'domain') {
$service->setAttribute('dns_records_count', $counts->get(mb_strtolower(trim((string) $service->server_name))));
}
}
}
public function findActiveBySlug(string $slug)
{
return $this->serviceClientRepository->findActiveBySlug($slug);
}
public function getDetailService(string $uuid, int $customerId)
{
return $this->serviceClientRepository->getDetailService($uuid, $customerId);
}
}