고객사 목록 쿼리스트링 연동 및 공통 JSON 파서 도입

This commit is contained in:
JiWoong Sul
2025-09-25 20:13:46 +09:00
parent 8a6ad1e81b
commit 900990c46b
27 changed files with 1458 additions and 176 deletions

View File

@@ -0,0 +1,71 @@
/// JSON 응답 형태를 일관되게 다루기 위한 헬퍼 모음.
class JsonUtils {
JsonUtils._();
/// 리스트 응답을 추출한다.
///
/// - [source]가 List이면 맵 형태의 요소만 반환한다.
/// - Map이면 [keys] 순서대로 탐색하며 List/Map을 찾아 리스트로 변환한다.
static List<Map<String, dynamic>> extractList(
dynamic source, {
List<String> keys = const ['items', 'data', 'results'],
}) {
if (source is List) {
return source.whereType<Map<String, dynamic>>().toList(growable: false);
}
if (source is Map<String, dynamic>) {
for (final key in keys) {
if (!source.containsKey(key)) continue;
final value = source[key];
if (value is List) {
return value.whereType<Map<String, dynamic>>().toList(
growable: false,
);
}
if (value is Map<String, dynamic>) {
return [value];
}
}
}
return const [];
}
/// Map 응답을 추출한다. 기본적으로 `data` 키를 우선 확인한다.
static Map<String, dynamic> extractMap(
dynamic source, {
List<String> keys = const ['data'],
}) {
if (source is Map<String, dynamic>) {
for (final key in keys) {
final value = source[key];
if (value is Map<String, dynamic>) {
return value;
}
}
return source;
}
return const {};
}
/// 맵에서 정수 값을 안전하게 읽는다. 문자열/실수도 허용한다.
static int readInt(
Map<String, dynamic>? source,
String key, {
int fallback = 0,
}) {
if (source == null) {
return fallback;
}
final value = source[key];
if (value is int) {
return value;
}
if (value is double) {
return value.round();
}
if (value is String) {
return int.tryParse(value) ?? fallback;
}
return fallback;
}
}