feat: 견적 시뮬레이터 개선 및 FlowTester 조건 평가기 추가

- 견적 시뮬레이터 UI 레이아웃 개선 (가로 배치, 반응형)
- FlowTester ConditionEvaluator 클래스 추가 (조건부 실행 지원)
- FormulaEvaluatorService 기능 확장
- DependencyResolver 의존성 해결 로직 개선
- PushDeviceToken 모델 확장 (FCM 토큰 관리)
- QuoteFormula API 엔드포인트 추가
- FlowTester 가이드 모달 업데이트
This commit is contained in:
2025-12-23 23:41:37 +09:00
parent f5ec9d502c
commit 60618ddd04
14 changed files with 1892 additions and 349 deletions

View File

@@ -32,6 +32,89 @@ class PushDeviceToken extends Model
'last_error_at' => 'datetime',
];
/**
* User-Agent에서 파싱된 기기명
*/
public function getParsedDeviceNameAttribute(): string
{
if (empty($this->device_name)) {
return '-';
}
// User-Agent 문자열인 경우 파싱
if (str_contains($this->device_name, 'Mozilla/') || str_contains($this->device_name, 'AppleWebKit')) {
return $this->parseUserAgent($this->device_name);
}
// 이미 간단한 기기명인 경우 그대로 반환
return $this->device_name;
}
/**
* User-Agent에서 파싱된 OS 버전
*/
public function getParsedOsVersionAttribute(): ?string
{
if (empty($this->device_name)) {
return null;
}
// Android 버전 추출
if (preg_match('/Android\s+([\d.]+)/', $this->device_name, $matches)) {
return 'Android ' . $matches[1];
}
// iOS 버전 추출
if (preg_match('/iPhone\s+OS\s+([\d_]+)/', $this->device_name, $matches)) {
return 'iOS ' . str_replace('_', '.', $matches[1]);
}
// iPad 버전 추출
if (preg_match('/CPU\s+OS\s+([\d_]+)/', $this->device_name, $matches)) {
return 'iOS ' . str_replace('_', '.', $matches[1]);
}
return null;
}
/**
* User-Agent 문자열에서 기기명 추출
*/
private function parseUserAgent(string $userAgent): string
{
// Android 기기명 추출: (Linux; Android 10; SM-N960N Build/...)
if (preg_match('/;\s*([A-Za-z0-9\-_]+(?:\s+[A-Za-z0-9\-_]+)*)\s+Build\//', $userAgent, $matches)) {
return trim($matches[1]);
}
// Android 기기명 대체 패턴: Android X; MODEL)
if (preg_match('/Android\s+[\d.]+;\s*([^)]+)\)/', $userAgent, $matches)) {
$model = trim($matches[1]);
// Build/ 이전까지만 추출
if (($pos = strpos($model, ' Build')) !== false) {
$model = substr($model, 0, $pos);
}
return $model ?: 'Android Device';
}
// iPhone 추출
if (str_contains($userAgent, 'iPhone')) {
return 'iPhone';
}
// iPad 추출
if (str_contains($userAgent, 'iPad')) {
return 'iPad';
}
// 기타 - 너무 긴 경우 축약
if (strlen($userAgent) > 30) {
return 'Unknown Device';
}
return $userAgent;
}
/**
* 플랫폼 상수
*/