Files
bowlingManager/mobile/lib/services/public_event_service.dart
T

163 lines
4.8 KiB
Dart

import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../config/api_config.dart';
import '../utils/web_storage.dart';
abstract class PublicHttpClient {
Future<Response<dynamic>> get(String path, {Map<String, dynamic>? headers});
Future<Response<dynamic>> post(String path, {dynamic data, Map<String, dynamic>? headers});
Future<Response<dynamic>> put(String path, {dynamic data, Map<String, dynamic>? headers});
}
class DioPublicHttpClient implements PublicHttpClient {
final Dio _dio;
DioPublicHttpClient({Dio? dio}) : _dio = dio ?? Dio(BaseOptions(
baseUrl: ApiConfig.baseUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
contentType: 'application/json',
));
@override
Future<Response> get(String path, {Map<String, dynamic>? headers}) {
return _dio.get(path, options: Options(headers: headers));
}
@override
Future<Response> post(String path, {data, Map<String, dynamic>? headers}) {
return _dio.post(path, data: data ?? {}, options: Options(headers: headers));
}
@override
Future<Response> put(String path, {data, Map<String, dynamic>? headers}) {
return _dio.put(path, data: data ?? {}, options: Options(headers: headers));
}
}
class PublicEventService {
final PublicHttpClient _http;
PublicEventService() : _http = DioPublicHttpClient();
@visibleForTesting
PublicEventService.forTest(this._http);
static String tokenKey(String publicHash) => 'event_token_' + publicHash;
String? getSavedToken(String publicHash) {
return WebStorage.getItem(tokenKey(publicHash));
}
void saveToken(String publicHash, String token) {
WebStorage.setItem(tokenKey(publicHash), token);
}
void removeToken(String publicHash) {
WebStorage.removeItem(tokenKey(publicHash));
}
Map<String, dynamic>? _authHeader(String? token) {
if (token == null || token.isEmpty) return null;
return { 'Authorization': 'Bearer ' + token };
}
Future<Map<String, dynamic>> fetchEvent(String publicHash) async {
final saved = getSavedToken(publicHash);
final res = await _http.get(
'/public/' + publicHash,
headers: _authHeader(saved),
);
final data = res.data as Map<String, dynamic>;
return data;
}
Future<Map<String, dynamic>> enter(String publicHash, {String? password}) async {
final saved = getSavedToken(publicHash);
try {
// 우선 저장된 토큰으로 시도, 실패 시 비밀번호로 재시도는 서버가 처리
final res = await _http.post(
'/public/' + publicHash,
data: password != null ? { 'password': password } : {},
headers: _authHeader(saved),
);
final data = res.data as Map<String, dynamic>;
// 응답에 token이 있으면 저장
final token = data['token']?.toString();
if (token != null && token.isNotEmpty) {
saveToken(publicHash, token);
}
return data;
} on DioException catch (e) {
final status = e.response?.statusCode;
if (status == 401 || status == 403) {
removeToken(publicHash);
}
rethrow;
}
}
Future<void> addOrUpdateParticipant(String publicHash, {
String? participantId,
required String memberId,
required String status,
required String paymentStatus,
String? comment,
}) async {
final token = getSavedToken(publicHash);
final payload = {
if (participantId != null) 'participantId': participantId,
'memberId': memberId,
'status': status,
'paymentStatus': paymentStatus,
if (comment != null) 'comment': comment,
};
await _http.post(
'/public/' + publicHash + '/participant',
data: payload,
headers: _authHeader(token),
);
}
Future<void> addGuest(String publicHash, {
required String name,
String? phone,
String? gender,
num? average,
}) async {
final token = getSavedToken(publicHash);
final payload = {
'name': name,
if (phone != null) 'phone': phone,
if (gender != null) 'gender': gender,
if (average != null) 'average': average,
};
await _http.post(
'/public/' + publicHash + '/guest',
data: payload,
headers: _authHeader(token),
);
}
Future<void> updateScore(String publicHash, {
required String participantId,
required int gameNumber,
required int score,
int? handicap,
dynamic teamNumber,
}) async {
final token = getSavedToken(publicHash);
final payload = {
'participantId': participantId,
'gameNumber': gameNumber,
'score': score,
if (handicap != null) 'handicap': handicap,
if (teamNumber != null) 'teamNumber': teamNumber,
};
await _http.put(
'/public/' + publicHash + '/score',
data: payload,
headers: _authHeader(token),
);
}
}