73 lines
2.4 KiB
PHP
73 lines
2.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Services;
|
||
|
|
|
||
|
|
use App\Models\Tenants\AiPricingConfig;
|
||
|
|
use App\Models\Tenants\AiTokenUsage;
|
||
|
|
|
||
|
|
class AiTokenUsageService extends Service
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 토큰 사용량 목록 + 통계
|
||
|
|
*/
|
||
|
|
public function list(array $params): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
|
||
|
|
$query = AiTokenUsage::where('tenant_id', $tenantId)
|
||
|
|
->when($params['start_date'] ?? null, fn ($q, $d) => $q->whereDate('created_at', '>=', $d))
|
||
|
|
->when($params['end_date'] ?? null, fn ($q, $d) => $q->whereDate('created_at', '<=', $d))
|
||
|
|
->when($params['menu_name'] ?? null, fn ($q, $m) => $q->where('menu_name', $m));
|
||
|
|
|
||
|
|
// 통계 (페이지네이션 전 전체 집계)
|
||
|
|
$stats = (clone $query)->selectRaw('
|
||
|
|
COUNT(*) as total_count,
|
||
|
|
COALESCE(SUM(prompt_tokens), 0) as total_prompt_tokens,
|
||
|
|
COALESCE(SUM(completion_tokens), 0) as total_completion_tokens,
|
||
|
|
COALESCE(SUM(total_tokens), 0) as total_total_tokens,
|
||
|
|
COALESCE(SUM(cost_usd), 0) as total_cost_usd,
|
||
|
|
COALESCE(SUM(cost_krw), 0) as total_cost_krw
|
||
|
|
')->first();
|
||
|
|
|
||
|
|
// 목록 (페이지네이션)
|
||
|
|
$items = $query->with('creator:id,name')
|
||
|
|
->orderByDesc('created_at')
|
||
|
|
->paginate($params['per_page'] ?? 20);
|
||
|
|
|
||
|
|
// 메뉴명 필터 옵션
|
||
|
|
$menuNames = AiTokenUsage::where('tenant_id', $tenantId)
|
||
|
|
->select('menu_name')
|
||
|
|
->distinct()
|
||
|
|
->orderBy('menu_name')
|
||
|
|
->pluck('menu_name');
|
||
|
|
|
||
|
|
return [
|
||
|
|
'items' => $items,
|
||
|
|
'stats' => [
|
||
|
|
'total_count' => (int) $stats->total_count,
|
||
|
|
'total_prompt_tokens' => (int) $stats->total_prompt_tokens,
|
||
|
|
'total_completion_tokens' => (int) $stats->total_completion_tokens,
|
||
|
|
'total_total_tokens' => (int) $stats->total_total_tokens,
|
||
|
|
'total_cost_usd' => (float) $stats->total_cost_usd,
|
||
|
|
'total_cost_krw' => (float) $stats->total_cost_krw,
|
||
|
|
],
|
||
|
|
'menu_names' => $menuNames,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 단가 설정 조회 (읽기 전용)
|
||
|
|
*/
|
||
|
|
public function getPricing(): array
|
||
|
|
{
|
||
|
|
$configs = AiPricingConfig::where('is_active', true)
|
||
|
|
->orderBy('provider')
|
||
|
|
->get();
|
||
|
|
|
||
|
|
return [
|
||
|
|
'pricing' => $configs,
|
||
|
|
'exchange_rate' => AiPricingConfig::getExchangeRate(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|