tdd 진행
This commit is contained in:
@@ -3,17 +3,33 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../config/api_config.dart';
|
||||
import '../models/event_model.dart';
|
||||
import '../models/participant_model.dart';
|
||||
import '../models/score_model.dart';
|
||||
import '../models/team_model.dart';
|
||||
import './api_service.dart';
|
||||
|
||||
class EventService with ChangeNotifier {
|
||||
List<Event> _events = [];
|
||||
Event? _currentEvent;
|
||||
List<Participant> _participants = [];
|
||||
List<Score> _scores = [];
|
||||
List<Team> _teams = [];
|
||||
bool _isLoading = false;
|
||||
String? _token;
|
||||
final ApiService _apiService = ApiService();
|
||||
ApiService _apiService;
|
||||
String? _clubId;
|
||||
|
||||
// 기본 생성자
|
||||
EventService() : _apiService = ApiService();
|
||||
|
||||
// 테스트용 생성자
|
||||
EventService.forTest(this._apiService);
|
||||
|
||||
List<Event> get events => [..._events];
|
||||
Event? get currentEvent => _currentEvent;
|
||||
List<Participant> get participants => [..._participants];
|
||||
List<Score> get scores => [..._scores];
|
||||
List<Team> get teams => [..._teams];
|
||||
bool get isLoading => _isLoading;
|
||||
|
||||
// 초기화 함수
|
||||
@@ -182,4 +198,464 @@ class EventService with ChangeNotifier {
|
||||
throw Exception('이벤트 삭제에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 참가자 관리 기능
|
||||
// 이벤트 참가자 목록 가져오기
|
||||
Future<List<Participant>> fetchEventParticipants(String eventId) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/participants',
|
||||
data: {'eventId': eventId},
|
||||
);
|
||||
|
||||
final List<dynamic> participantsData = data['participants'] ?? [];
|
||||
_participants = participantsData
|
||||
.map((participantData) => Participant.fromJson(participantData))
|
||||
.toList();
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return _participants;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('참가자 목록을 불러오는데 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 참가자 추가
|
||||
Future<Participant> addParticipant(
|
||||
String eventId,
|
||||
Map<String, dynamic> participantData,
|
||||
) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/$eventId/participants',
|
||||
data: participantData,
|
||||
);
|
||||
|
||||
final newParticipant = Participant.fromJson(data['participant']);
|
||||
|
||||
_participants.add(newParticipant);
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return newParticipant;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('참가자 추가에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 참가자 정보 업데이트
|
||||
Future<Participant> updateParticipant(
|
||||
String eventId,
|
||||
String participantId,
|
||||
Map<String, dynamic> updates,
|
||||
) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.put(
|
||||
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
|
||||
data: updates,
|
||||
);
|
||||
|
||||
final updatedParticipant = Participant.fromJson(data['participant']);
|
||||
|
||||
// 참가자 목록 업데이트
|
||||
final index = _participants.indexWhere(
|
||||
(participant) => participant.id == participantId,
|
||||
);
|
||||
if (index >= 0) {
|
||||
_participants[index] = updatedParticipant;
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return updatedParticipant;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('참가자 정보 업데이트에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 참가자 삭제
|
||||
Future<bool> removeParticipant(String eventId, String participantId) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
await _apiService.delete(
|
||||
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
|
||||
);
|
||||
|
||||
// 참가자 목록에서 삭제
|
||||
_participants.removeWhere(
|
||||
(participant) => participant.id == participantId,
|
||||
);
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('참가자 삭제에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 참가자 상태 업데이트
|
||||
Future<Participant> updateParticipantStatus(
|
||||
String eventId,
|
||||
String participantId,
|
||||
String status,
|
||||
) async {
|
||||
return updateParticipant(eventId, participantId, {'status': status});
|
||||
}
|
||||
|
||||
// 점수 관리 기능
|
||||
// 이벤트 점수 목록 가져오기
|
||||
Future<List<Score>> fetchEventScores(String eventId) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/scores',
|
||||
data: {'eventId': eventId},
|
||||
);
|
||||
|
||||
final List<dynamic> scoresData = data['scores'] ?? [];
|
||||
_scores = scoresData
|
||||
.map((scoreData) => Score.fromJson(scoreData))
|
||||
.toList();
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return _scores;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('점수 목록을 불러오는데 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 점수 추가
|
||||
Future<Score> addScore(String eventId, Map<String, dynamic> scoreData) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/$eventId/scores',
|
||||
data: scoreData,
|
||||
);
|
||||
|
||||
final newScore = Score.fromJson(data['score']);
|
||||
|
||||
_scores.add(newScore);
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return newScore;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('점수 추가에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 점수 업데이트
|
||||
Future<Score> updateScore(
|
||||
String eventId,
|
||||
String scoreId,
|
||||
Map<String, dynamic> updates,
|
||||
) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.put(
|
||||
'${ApiConfig.clubs}/events/$eventId/scores/$scoreId',
|
||||
data: updates,
|
||||
);
|
||||
|
||||
final updatedScore = Score.fromJson(data['score']);
|
||||
|
||||
// 점수 목록 업데이트
|
||||
final index = _scores.indexWhere((score) => score.id == scoreId);
|
||||
if (index >= 0) {
|
||||
_scores[index] = updatedScore;
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return updatedScore;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('점수 업데이트에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 점수 삭제
|
||||
Future<bool> deleteScore(String eventId, String scoreId) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
await _apiService.delete(
|
||||
'${ApiConfig.clubs}/events/$eventId/scores/$scoreId',
|
||||
);
|
||||
|
||||
// 점수 목록에서 삭제
|
||||
_scores.removeWhere((score) => score.id == scoreId);
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('점수 삭제에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 팀 관리 기능
|
||||
// 이벤트 팀 목록 가져오기
|
||||
Future<List<Team>> fetchEventTeams(String eventId) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/teams',
|
||||
data: {'eventId': eventId},
|
||||
);
|
||||
|
||||
final List<dynamic> teamsData = data['teams'] ?? [];
|
||||
_teams = teamsData.map((teamData) => Team.fromJson(teamData)).toList();
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return _teams;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('팀 목록을 불러오는데 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 팀 생성
|
||||
Future<List<Team>> generateTeams(
|
||||
String eventId,
|
||||
Map<String, dynamic> teamConfig,
|
||||
) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/$eventId/teams/generate',
|
||||
data: teamConfig,
|
||||
);
|
||||
|
||||
final List<dynamic> teamsData = data['teams'] ?? [];
|
||||
_teams = teamsData.map((teamData) => Team.fromJson(teamData)).toList();
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return _teams;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('팀 생성에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 팀 저장
|
||||
Future<bool> saveTeams(String eventId, List<Team> teams) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
await _apiService.post(
|
||||
'${ApiConfig.clubs}/events/$eventId/teams/save',
|
||||
data: {'teams': teams.map((team) => team.toJson()).toList()},
|
||||
);
|
||||
|
||||
_teams = teams;
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('팀 저장에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 파일에서 이벤트 일괄 생성
|
||||
Future<List<Event>> createEventsFromFile(
|
||||
List<Map<String, dynamic>> eventsData,
|
||||
) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final List<Event> createdEvents = [];
|
||||
|
||||
// 각 이벤트 데이터에 클럽 ID 추가
|
||||
for (var eventData in eventsData) {
|
||||
eventData['clubId'] = _clubId;
|
||||
|
||||
// null 값 처리 - 빈 문자열을 명시적 null로 변환
|
||||
eventData.forEach((key, value) {
|
||||
if (value is String && value.isEmpty) {
|
||||
eventData[key] = null;
|
||||
}
|
||||
});
|
||||
|
||||
// 이벤트 생성 API 호출
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events',
|
||||
data: eventData,
|
||||
);
|
||||
|
||||
final newEvent = Event.fromJson(data['event']);
|
||||
createdEvents.add(newEvent);
|
||||
_events.add(newEvent);
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return createdEvents;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('파일에서 이벤트 생성에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 이벤트 복제
|
||||
Future<Event> cloneEvent(String eventId, {String? newName}) async {
|
||||
if (_token == null || _clubId == null) {
|
||||
throw Exception('인증 또는 클럽 정보가 필요합니다');
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// 원본 이벤트 정보 가져오기
|
||||
final originalEvent = await fetchEventById(eventId);
|
||||
|
||||
// 복제할 이벤트 데이터 준비
|
||||
final Map<String, dynamic> cloneData = {
|
||||
'clubId': _clubId,
|
||||
'title': newName ?? '${originalEvent.title} (복사본)',
|
||||
'description': originalEvent.description,
|
||||
'location': originalEvent.location,
|
||||
'type': originalEvent.type,
|
||||
'status': 'draft', // 복제된 이벤트는 초안 상태로 시작
|
||||
'startDate': originalEvent.startDate.toIso8601String(),
|
||||
'endDate': originalEvent.endDate?.toIso8601String(),
|
||||
'maxParticipants': originalEvent.maxParticipants,
|
||||
'participantFee': originalEvent.participantFee,
|
||||
'gameCount': originalEvent.gameCount,
|
||||
'publicHash': originalEvent.publicHash,
|
||||
'accessPassword': originalEvent.accessPassword,
|
||||
'isActive': true,
|
||||
};
|
||||
|
||||
// 이벤트 생성 API 호출
|
||||
final data = await _apiService.post(
|
||||
'${ApiConfig.clubs}/events',
|
||||
data: cloneData,
|
||||
);
|
||||
|
||||
final newEvent = Event.fromJson(data['event']);
|
||||
_events.add(newEvent);
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return newEvent;
|
||||
} catch (e) {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
throw Exception('이벤트 복제에 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user