- 전체 371개 파일 중 82개 미사용 파일 식별 - Phase 1: 33개 파일 삭제 예정 (100% 안전) - Phase 2: 30개 파일 삭제 검토 예정 - Phase 3: 19개 파일 수동 검토 예정 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
181 lines
6.8 KiB
Dart
181 lines
6.8 KiB
Dart
import 'package:dartz/dartz.dart';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:injectable/injectable.dart';
|
|
import 'package:superport/core/errors/failures.dart';
|
|
import 'package:superport/data/datasources/remote/api_client.dart';
|
|
import 'package:superport/core/constants/api_endpoints.dart';
|
|
import 'package:superport/data/models/lookups/lookup_data.dart';
|
|
|
|
abstract class LookupRemoteDataSource {
|
|
Future<Either<Failure, LookupData>> getAllLookups();
|
|
Future<Either<Failure, LookupData>> getLookupsByType(String type);
|
|
}
|
|
|
|
@LazySingleton(as: LookupRemoteDataSource)
|
|
class LookupRemoteDataSourceImpl implements LookupRemoteDataSource {
|
|
final ApiClient _apiClient;
|
|
|
|
LookupRemoteDataSourceImpl(this._apiClient);
|
|
|
|
@override
|
|
Future<Either<Failure, LookupData>> getAllLookups() async {
|
|
try {
|
|
debugPrint('📞 === LOOKUP 개별 API 요청 시작 ===');
|
|
|
|
// 개별 API들을 병렬로 호출
|
|
final List<Future> futures = [
|
|
_apiClient.get(ApiEndpoints.lookupsVendors),
|
|
_apiClient.get(ApiEndpoints.lookupsCompanies),
|
|
_apiClient.get(ApiEndpoints.lookupsWarehouses),
|
|
];
|
|
|
|
final responses = await Future.wait(futures, eagerError: false);
|
|
|
|
debugPrint('📊 === LOOKUP 개별 API 응답 ===');
|
|
|
|
// Vendors 데이터 처리
|
|
List<LookupItem> manufacturers = [];
|
|
try {
|
|
final vendorsResponse = responses[0] as Response;
|
|
if (vendorsResponse.data is List) {
|
|
manufacturers = (vendorsResponse.data as List)
|
|
.map((v) => LookupItem(
|
|
id: v['id'] as int?,
|
|
name: v['name'] as String
|
|
))
|
|
.toList();
|
|
debugPrint('✅ 제조사 데이터: ${manufacturers.length}개');
|
|
}
|
|
} catch (e) {
|
|
debugPrint('⚠️ 제조사 데이터 처리 실패: $e');
|
|
}
|
|
|
|
// Companies 데이터 처리
|
|
List<LookupItem> companies = [];
|
|
try {
|
|
final companiesResponse = responses[1] as Response;
|
|
if (companiesResponse.data is List) {
|
|
companies = (companiesResponse.data as List)
|
|
.map((c) => LookupItem(
|
|
id: c['id'] as int?,
|
|
name: c['name'] as String
|
|
))
|
|
.toList();
|
|
debugPrint('✅ 회사 데이터: ${companies.length}개');
|
|
}
|
|
} catch (e) {
|
|
debugPrint('⚠️ 회사 데이터 처리 실패: $e');
|
|
}
|
|
|
|
// Warehouses 데이터 처리
|
|
List<LookupItem> warehouses = [];
|
|
try {
|
|
final warehousesResponse = responses[2] as Response;
|
|
if (warehousesResponse.data is List) {
|
|
warehouses = (warehousesResponse.data as List)
|
|
.map((w) => LookupItem(
|
|
id: w['id'] as int?,
|
|
name: w['name'] as String
|
|
))
|
|
.toList();
|
|
debugPrint('✅ 창고 데이터: ${warehouses.length}개');
|
|
}
|
|
} catch (e) {
|
|
debugPrint('⚠️ 창고 데이터 처리 실패: $e');
|
|
}
|
|
|
|
// 통합된 LookupData 생성
|
|
final lookupData = LookupData(
|
|
manufacturers: manufacturers,
|
|
companies: companies,
|
|
warehouses: warehouses,
|
|
equipmentNames: [], // 현재 백엔드에서 제공하지 않음
|
|
equipmentCategories: [], // 현재 백엔드에서 제공하지 않음
|
|
equipmentStatuses: [], // 현재 백엔드에서 제공하지 않음
|
|
);
|
|
|
|
debugPrint('📊 통합 Lookup 데이터 생성 완료');
|
|
return Right(lookupData);
|
|
|
|
} on DioException catch (e) {
|
|
debugPrint('❌ === LOOKUP API DIO 에러 ===');
|
|
debugPrint('❌ 에러 타입: ${e.type}');
|
|
debugPrint('❌ 상태 코드: ${e.response?.statusCode}');
|
|
debugPrint('❌ 에러 메시지: ${e.message}');
|
|
|
|
// 개별 API 오류의 경우 빈 데이터로 fallback
|
|
return Right(LookupData.empty());
|
|
} catch (e) {
|
|
debugPrint('❌ === LOOKUP API 일반 에러 ===');
|
|
debugPrint('❌ 에러: $e');
|
|
return Left(ServerFailure(message: '조회 데이터를 가져오는 중 오류가 발생했습니다: $e'));
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<Either<Failure, LookupData>> getLookupsByType(String type) async {
|
|
try {
|
|
final response = await _apiClient.get(
|
|
'${ApiEndpoints.lookups}/type',
|
|
queryParameters: {'lookup_type': type},
|
|
);
|
|
|
|
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
|
// 타입별 조회도 전체 LookupData 형식으로 반환 - IdentityMap 타입 오류 수정
|
|
try {
|
|
final lookupData = LookupData.fromJson(response.data['data'] as Map<String, dynamic>);
|
|
return Right(lookupData);
|
|
} catch (jsonError) {
|
|
debugPrint('❌ LookupData JSON 파싱 오류: $jsonError');
|
|
debugPrint('❌ 응답 데이터: ${response.data['data']}');
|
|
// JSON 파싱 실패 시 빈 데이터 반환
|
|
return Right(LookupData.empty());
|
|
}
|
|
} else {
|
|
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 올바르지 않습니다';
|
|
return Left(ServerFailure(message: errorMessage));
|
|
}
|
|
} on DioException catch (e) {
|
|
return Left(_handleDioError(e));
|
|
} catch (e) {
|
|
debugPrint('❌ getLookupsByType 일반 오류: $e');
|
|
return Left(ServerFailure(message: '타입별 조회 데이터를 가져오는 중 오류가 발생했습니다: $e'));
|
|
}
|
|
}
|
|
|
|
Failure _handleDioError(DioException error) {
|
|
switch (error.type) {
|
|
case DioExceptionType.connectionTimeout:
|
|
case DioExceptionType.sendTimeout:
|
|
case DioExceptionType.receiveTimeout:
|
|
return NetworkFailure(message: '네트워크 연결 시간이 초과되었습니다');
|
|
case DioExceptionType.connectionError:
|
|
return NetworkFailure(message: '서버에 연결할 수 없습니다');
|
|
case DioExceptionType.badResponse:
|
|
final statusCode = error.response?.statusCode ?? 0;
|
|
final errorData = error.response?.data;
|
|
|
|
String message;
|
|
if (errorData is Map) {
|
|
message = errorData['error']?['message'] ??
|
|
errorData['message'] ??
|
|
'서버 오류가 발생했습니다';
|
|
} else {
|
|
message = '서버 오류가 발생했습니다';
|
|
}
|
|
|
|
if (statusCode == 401) {
|
|
return AuthenticationFailure(message: '인증이 만료되었습니다');
|
|
} else if (statusCode == 403) {
|
|
return AuthenticationFailure(message: '접근 권한이 없습니다');
|
|
} else {
|
|
return ServerFailure(message: message);
|
|
}
|
|
case DioExceptionType.cancel:
|
|
return ServerFailure(message: '요청이 취소되었습니다');
|
|
default:
|
|
return ServerFailure(message: '알 수 없는 오류가 발생했습니다');
|
|
}
|
|
}
|
|
} |