- CLAUDE.md 대폭 개선: 개발 가이드라인 및 프로젝트 상태 문서화 - 백엔드 API 통합: 모든 엔티티 간 Foreign Key 관계 완벽 구현 - UI 일관성 강화: shadcn_ui 컴포넌트 표준화 적용 - 데이터 모델 개선: DTO 및 모델 클래스 백엔드 스키마와 100% 일치 - 사용자 관리: 회사 연결, 중복 검사, 입력 검증 기능 추가 - 창고 관리: 우편번호 연결, 중복 검사 기능 강화 - 회사 관리: 우편번호 연결, 중복 검사 로직 구현 - 장비 관리: 불필요한 카테고리 필드 제거, 벤더-모델 관계 정리 - 우편번호 시스템: 검색 다이얼로그 Provider 버그 수정 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
154 lines
5.0 KiB
Dart
154 lines
5.0 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,
|
|
});
|
|
|
|
Future<EquipmentDto> createEquipment(EquipmentRequestDto request);
|
|
|
|
Future<EquipmentDto> getEquipmentDetail(int id);
|
|
|
|
Future<EquipmentDto> updateEquipment(int id, EquipmentUpdateRequestDto request);
|
|
|
|
Future<void> deleteEquipment(int id);
|
|
}
|
|
|
|
class EquipmentRemoteDataSourceImpl implements EquipmentRemoteDataSource {
|
|
final ApiClient _apiClient = GetIt.instance<ApiClient>();
|
|
|
|
@override
|
|
Future<EquipmentListResponse> getEquipments({
|
|
int page = 1,
|
|
int perPage = 20,
|
|
String? search,
|
|
}) async {
|
|
try {
|
|
final queryParams = <String, dynamic>{
|
|
'page': page,
|
|
'page_size': perPage,
|
|
if (search != null && search.isNotEmpty) 'search': search,
|
|
};
|
|
|
|
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) {
|
|
throw ServerException(
|
|
message: e.response?.data['message'] ?? 'Network error occurred',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
@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) {
|
|
throw ServerException(
|
|
message: e.response?.data['message'] ?? 'Network error occurred',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
@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) {
|
|
throw ServerException(
|
|
message: e.response?.data['message'] ?? 'Network error occurred',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
@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) {
|
|
throw ServerException(
|
|
message: e.response?.data['message'] ?? 'Network error occurred',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> deleteEquipment(int id) async {
|
|
try {
|
|
await _apiClient.delete('${ApiEndpoints.equipment}/$id');
|
|
} on DioException catch (e) {
|
|
throw ServerException(
|
|
message: e.response?.data['message'] ?? 'Network error occurred',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
} |