Files
superport/lib/data/datasources/remote/equipment_remote_datasource.dart
JiWoong Sul c419f8f458 backup: 사용하지 않는 파일 삭제 전 복구 지점
- 전체 371개 파일 중 82개 미사용 파일 식별
- Phase 1: 33개 파일 삭제 예정 (100% 안전)
- Phase 2: 30개 파일 삭제 검토 예정
- Phase 3: 19개 파일 수동 검토 예정

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 19:51:40 +09:00

242 lines
7.9 KiB
Dart

import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/equipment/equipment_dto.dart';
abstract class EquipmentRemoteDataSource {
Future<EquipmentListResponse> getEquipments({
int page = 1,
int perPage = 20,
String? search,
int? companyId,
});
Future<EquipmentDto> createEquipment(EquipmentRequestDto request);
Future<EquipmentDto> getEquipmentDetail(int id);
Future<EquipmentDto> updateEquipment(int id, EquipmentUpdateRequestDto request);
Future<void> deleteEquipment(int id);
Future<EquipmentDto> restoreEquipment(int id);
Future<EquipmentDto> getEquipmentBySerial(String serial);
Future<EquipmentDto> getEquipmentByBarcode(String barcode);
Future<List<EquipmentDto>> getEquipmentsByCompany(int companyId);
}
class EquipmentRemoteDataSourceImpl implements EquipmentRemoteDataSource {
final ApiClient _apiClient = GetIt.instance<ApiClient>();
/// DioException을 ServerException으로 변환하는 헬퍼 메서드
Never _handleDioException(DioException e) {
String errorMessage = 'Network error occurred';
if (e.response?.data != null) {
// 응답 데이터가 Map인 경우 (JSON 에러)
if (e.response!.data is Map<String, dynamic>) {
final errorData = e.response!.data as Map<String, dynamic>;
errorMessage = errorData['error']?['message'] ??
errorData['message'] ??
'Server error occurred';
}
// 응답 데이터가 String인 경우 (Plain text 에러)
else if (e.response!.data is String) {
errorMessage = e.response!.data as String;
}
}
throw ServerException(
message: errorMessage,
statusCode: e.response?.statusCode,
);
}
@override
Future<EquipmentListResponse> getEquipments({
int page = 1,
int perPage = 20,
String? search,
int? companyId,
}) async {
try {
final queryParams = <String, dynamic>{
'page': page,
'page_size': perPage,
if (search != null && search.isNotEmpty) 'search': search,
if (companyId != null) 'company_id': companyId,
};
final response = await _apiClient.get(
ApiEndpoints.equipment,
queryParameters: queryParams,
);
print('[Equipment API] Response: ${response.data}');
// 백엔드 응답은 직접 data 배열과 페이지네이션 정보 반환
final Map<String, dynamic> responseData = response.data;
return EquipmentListResponse.fromJson(responseData);
} on DioException catch (e) {
_handleDioException(e);
}
}
@override
Future<EquipmentDto> createEquipment(EquipmentRequestDto request) async {
try {
final response = await _apiClient.post(
ApiEndpoints.equipment,
data: request.toJson(),
);
print('[Equipment API] Create Response: ${response.data}');
// API 응답이 {success: true, data: {...}} 형태인 경우 처리
final responseData = response.data;
if (responseData is Map && responseData.containsKey('data')) {
return EquipmentDto.fromJson(responseData['data']);
} else {
// 직접 데이터인 경우
return EquipmentDto.fromJson(responseData);
}
} on DioException catch (e) {
_handleDioException(e);
}
}
@override
Future<EquipmentDto> getEquipmentDetail(int id) async {
try {
final response = await _apiClient.get('${ApiEndpoints.equipment}/$id');
print('[Equipment API] Detail Response: ${response.data}');
// API 응답이 {success: true, data: {...}} 형태인 경우 처리
final responseData = response.data;
if (responseData is Map && responseData.containsKey('data')) {
return EquipmentDto.fromJson(responseData['data']);
} else {
// 직접 데이터인 경우
return EquipmentDto.fromJson(responseData);
}
} on DioException catch (e) {
_handleDioException(e);
}
}
@override
Future<EquipmentDto> updateEquipment(int id, EquipmentUpdateRequestDto request) async {
try {
// 디버그: 전송할 JSON 데이터 로깅
final jsonData = request.toJson();
// null 필드 제거 (백엔드가 null을 처리하지 못하는 경우 대비)
final cleanedData = Map<String, dynamic>.from(jsonData)
..removeWhere((key, value) => value == null);
print('[Equipment API] Update Request JSON: $cleanedData');
print('[Equipment API] JSON keys: ${cleanedData.keys.toList()}');
final response = await _apiClient.put(
'${ApiEndpoints.equipment}/$id',
data: cleanedData,
);
print('[Equipment API] Update Response: ${response.data}');
// API 응답이 {success: true, data: {...}} 형태인 경우 처리
final responseData = response.data;
if (responseData is Map && responseData.containsKey('data')) {
return EquipmentDto.fromJson(responseData['data']);
} else {
// 직접 데이터인 경우
return EquipmentDto.fromJson(responseData);
}
} on DioException catch (e) {
_handleDioException(e);
}
}
@override
Future<void> deleteEquipment(int id) async {
try {
await _apiClient.delete('${ApiEndpoints.equipment}/$id');
} on DioException catch (e) {
_handleDioException(e);
}
}
@override
Future<EquipmentDto> restoreEquipment(int id) async {
try {
final response = await _apiClient.put('${ApiEndpoints.equipment}/$id/restore');
// 백엔드 응답 구조에 따라 data 필드에서 추출
final responseData = response.data;
return EquipmentDto.fromJson(responseData['data'] ?? responseData);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to restore equipment',
statusCode: e.response?.statusCode,
);
}
}
@override
Future<EquipmentDto> getEquipmentBySerial(String serial) async {
try {
final response = await _apiClient.get('${ApiEndpoints.equipment}/serial/$serial');
// 백엔드 응답 구조에 따라 data 필드에서 추출
final responseData = response.data;
return EquipmentDto.fromJson(responseData['data'] ?? responseData);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Equipment not found by serial',
statusCode: e.response?.statusCode,
);
}
}
@override
Future<EquipmentDto> getEquipmentByBarcode(String barcode) async {
try {
final response = await _apiClient.get('${ApiEndpoints.equipment}/barcode/$barcode');
// 백엔드 응답 구조에 따라 data 필드에서 추출
final responseData = response.data;
return EquipmentDto.fromJson(responseData['data'] ?? responseData);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Equipment not found by barcode',
statusCode: e.response?.statusCode,
);
}
}
@override
Future<List<EquipmentDto>> getEquipmentsByCompany(int companyId) async {
try {
final response = await _apiClient.get('${ApiEndpoints.equipment}/by-company/$companyId');
print('[Equipment API] Company Filter Response: ${response.data}');
// 백엔드 응답 구조에 따라 data 필드에서 추출
final responseData = response.data;
final List<dynamic> equipmentList = responseData['data'] ?? responseData;
return equipmentList.map((json) => EquipmentDto.fromJson(json)).toList();
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to get equipments by company',
statusCode: e.response?.statusCode,
);
}
}
}