LCOV - code coverage report

Current view: | top level - lib/services - score_service.dart |  |  | Coverage | Total | Hit
Test: | lcov.info |  | Lines: | 78.4 % | 134 | 105
Test Date: | 2025-08-12 03:21:51 |  | Functions: | - | 0 | 0

                Line data    Source code

           1              : import 'package:flutter/foundation.dart';
           2              : import 'package:shared_preferences/shared_preferences.dart';
           3              :
           4              : import '../config/api_config.dart';
           5              : import '../models/score_model.dart';
           6              : import './api_service.dart';
           7              :
           8              : class ScoreService with ChangeNotifier {
           9              :   List<Score> _scores = [];
          10              :   bool _isLoading = false;
          11              :   String? _token;
          12              :   String? _clubId;
          13              :   ApiService _apiService = ApiService();
          14              :   String? _memberId;
          15              :   String? _eventId;
          16              :
          17              :   // 테스트용 생성자
          18            2 :   ScoreService.forTest(ApiService apiService, {String? clubId, String? memberId, String? eventId}) {
          19            2 :     _apiService = apiService;
          20              :     if (clubId != null) {
          21            2 :       _clubId = clubId;
          22              :     }
          23              :     if (memberId != null) {
          24            0 :       _memberId = memberId;
          25              :     }
          26              :     if (eventId != null) {
          27            0 :       _eventId = eventId;
          28              :     }
          29              :   }
          30              :
          31              :   // 테스트용 getter
          32            2 :   String? get testMemberId => _memberId;
          33            2 :   String? get testEventId => _eventId;
          34              :
          35              :   // 기본 생성자
          36            0 :   ScoreService();
          37              :
          38            6 :   List<Score> get scores => [..._scores];
          39            0 :   bool get isLoading => _isLoading;
          40              :
          41              :   // 초기화 함수
          42            2 :   void initialize(String token) {
          43            2 :     _token = token;
          44            4 :     _apiService.setToken(token);
          45              :   }
          46              :
          47              :   // 회원 ID 설정
          48            1 :   void setMemberId(String memberId) {
          49            1 :     _memberId = memberId;
          50            1 :     notifyListeners();
          51              :   }
          52              :
          53              :   // 이벤트 ID 설정
          54            1 :   void setEventId(String eventId) {
          55            1 :     _eventId = eventId;
          56            1 :     notifyListeners();
          57              :   }
          58              :
          59              :   // 클럽의 모든 점수 가져오기
          60            2 :   Future<void> fetchClubScores() async {
          61            6 :     print('fetchClubScores 호출됨: token=$_token');
          62              :
          63            2 :     _isLoading = true;
          64            2 :     notifyListeners();
          65              :
          66              :     try {
          67              :       // 클럽 ID 가져오기
          68            2 :       final prefs = await SharedPreferences.getInstance();
          69            2 :       final clubId = prefs.getString(ApiConfig.clubIdKey);
          70              :
          71              :       if (clubId == null) {
          72            0 :         throw Exception('선택된 클럽이 없습니다');
          73              :       }
          74              :
          75            4 :       final data = await _apiService.post(
          76              :         '${ApiConfig.clubs}/scores',
          77            2 :         data: {'clubId': clubId},
          78              :       );
          79              :
          80              :       // 응답 데이터가 리스트 형태로 직접 왔는지 확인
          81            2 :       if (data is List) {
          82              :         final List<dynamic> scoresData = data;
          83            2 :         _scores = scoresData
          84            6 :             .map((scoreData) => Score.fromJson(scoreData))
          85            2 :             .toList();
          86              :       } else {
          87              :         // 응답 데이터가 객체 형태로 왔을 경우 scores 키를 통해 접근
          88            1 :         final List<dynamic> scoresData = data['scores'] ?? [];
          89            1 :         _scores = scoresData
          90            3 :             .map((scoreData) => Score.fromJson(scoreData))
          91            1 :             .toList();
          92              :       }
          93              :
          94            2 :       _isLoading = false;
          95            2 :       notifyListeners();
          96              :     } catch (e) {
          97            1 :       _isLoading = false;
          98            1 :       notifyListeners();
          99            2 :       throw Exception('점수 목록을 불러오는데 실패했습니다: $e');
         100              :     }
         101              :   }
         102              :
         103              :   // 회원의 점수 가져오기
         104            2 :   Future<List<Score>> fetchMemberScores(String memberId) async {
         105            4 :     if (_token == null || _clubId == null) {
         106            1 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         107              :     }
         108              :
         109            2 :     _isLoading = true;
         110            2 :     notifyListeners();
         111              :
         112              :     try {
         113            4 :       final data = await _apiService.post(
         114              :         '${ApiConfig.clubs}/members/scores',
         115            2 :         data: {'memberId': memberId},
         116              :       );
         117              :
         118            2 :       final List<dynamic> scoresData = data['scores'];
         119              :
         120              :       final memberScores = scoresData
         121            6 :           .map((scoreData) => Score.fromJson(scoreData))
         122            2 :           .toList();
         123              :
         124            2 :       _isLoading = false;
         125            2 :       notifyListeners();
         126              :
         127              :       return memberScores;
         128              :     } catch (e) {
         129            0 :       _isLoading = false;
         130            0 :       notifyListeners();
         131            0 :       throw Exception('회원 점수를 불러오는데 실패했습니다: $e');
         132              :     }
         133              :   }
         134              :
         135              :   // 이벤트의 점수 가져오기
         136            2 :   Future<List<Score>> fetchEventScores(String eventId) async {
         137            4 :     if (_token == null || _clubId == null) {
         138            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         139              :     }
         140              :
         141            2 :     _isLoading = true;
         142            2 :     notifyListeners();
         143              :
         144              :     try {
         145            4 :       final data = await _apiService.post(
         146              :         '${ApiConfig.clubs}/events/scores',
         147            2 :         data: {'eventId': eventId},
         148              :       );
         149              :
         150            2 :       final List<dynamic> scoresData = data['scores'];
         151              :
         152              :       final eventScores = scoresData
         153            6 :           .map((scoreData) => Score.fromJson(scoreData))
         154            2 :           .toList();
         155              :
         156            2 :       _isLoading = false;
         157            2 :       notifyListeners();
         158              :
         159              :       return eventScores;
         160              :     } catch (e) {
         161            0 :       _isLoading = false;
         162            0 :       notifyListeners();
         163            0 :       throw Exception('이벤트 점수를 불러오는데 실패했습니다: $e');
         164              :     }
         165              :   }
         166              :
         167              :   // 점수 추가
         168            2 :   Future<Score> addScore(Map<String, dynamic> scoreData) async {
         169            4 :     if (_token == null || _clubId == null) {
         170            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         171              :     }
         172              :
         173            2 :     _isLoading = true;
         174            2 :     notifyListeners();
         175              :
         176              :     try {
         177            4 :       final data = await _apiService.post(ApiConfig.scores, data: scoreData);
         178              :
         179            4 :       final newScore = Score.fromJson(data['score']);
         180              :
         181            4 :       _scores.add(newScore);
         182              :
         183            2 :       _isLoading = false;
         184            2 :       notifyListeners();
         185              :
         186              :       return newScore;
         187              :     } catch (e) {
         188            0 :       _isLoading = false;
         189            0 :       notifyListeners();
         190            0 :       throw Exception('점수 추가에 실패했습니다: $e');
         191              :     }
         192              :   }
         193              :
         194              :   // 점수 수정
         195            2 :   Future<Score> updateScore(
         196              :     String scoreId,
         197              :     Map<String, dynamic> updates,
         198              :   ) async {
         199            4 :     if (_token == null || _clubId == null) {
         200            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         201              :     }
         202              :
         203            2 :     _isLoading = true;
         204            2 :     notifyListeners();
         205              :
         206              :     try {
         207            4 :       final data = await _apiService.put(
         208            2 :         '${ApiConfig.scores}/$scoreId',
         209              :         data: updates,
         210              :       );
         211              :
         212            4 :       final updatedScore = Score.fromJson(data['score']);
         213              :
         214              :       // 점수 목록 업데이트
         215           10 :       final index = _scores.indexWhere((score) => score.id == scoreId);
         216            2 :       if (index >= 0) {
         217            4 :         _scores[index] = updatedScore;
         218              :       }
         219              :
         220            2 :       _isLoading = false;
         221            2 :       notifyListeners();
         222              :
         223              :       return updatedScore;
         224              :     } catch (e) {
         225            0 :       _isLoading = false;
         226            0 :       notifyListeners();
         227            0 :       throw Exception('점수 수정에 실패했습니다: $e');
         228              :     }
         229              :   }
         230              :
         231              :   // 점수 삭제
         232            2 :   Future<bool> deleteScore(String scoreId) async {
         233            4 :     if (_token == null || _clubId == null) {
         234            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         235              :     }
         236              :
         237            2 :     _isLoading = true;
         238            2 :     notifyListeners();
         239              :
         240              :     try {
         241            6 :       await _apiService.delete('${ApiConfig.scores}/$scoreId');
         242              :
         243              :       // 점수 목록에서 삭제
         244           10 :       _scores.removeWhere((score) => score.id == scoreId);
         245              :
         246            2 :       _isLoading = false;
         247            2 :       notifyListeners();
         248              :
         249              :       return true;
         250              :     } catch (e) {
         251            0 :       _isLoading = false;
         252            0 :       notifyListeners();
         253            0 :       throw Exception('점수 삭제에 실패했습니다: $e');
         254              :     }
         255              :   }
         256              :
         257              :   // 회원 통계 가져오기
         258            2 :   Future<ScoreStatistics> fetchMemberStatistics(String memberId) async {
         259            4 :     if (_token == null || _clubId == null) {
         260            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         261              :     }
         262              :
         263              :     try {
         264            4 :       final data = await _apiService.post(
         265              :         '${ApiConfig.clubs}/members/stats',
         266            2 :         data: {'memberId': memberId},
         267              :       );
         268              :
         269            4 :       return ScoreStatistics.fromJson(data['statistics']);
         270              :     } catch (e) {
         271            2 :       throw Exception('회원 통계를 불러오는데 실패했습니다: $e');
         272              :     }
         273              :   }
         274              :
         275              :   // 클럽 통계 가져오기
         276            2 :   Future<Map<String, ScoreStatistics>> fetchClubStatistics() async {
         277            2 :     if (_token == null) {
         278            0 :       throw Exception('인증 정보가 필요합니다');
         279              :     }
         280              :
         281              :     try {
         282              :       // 클럽 ID 가져오기
         283            2 :       final prefs = await SharedPreferences.getInstance();
         284            2 :       final clubId = prefs.getString(ApiConfig.clubIdKey);
         285              :
         286              :       if (clubId == null) {
         287            0 :         throw Exception('선택된 클럽이 없습니다');
         288              :       }
         289              :
         290            4 :       final data = await _apiService.post(
         291              :         '${ApiConfig.clubs}/scores/stats',
         292            2 :         data: {'clubId': clubId},
         293              :       );
         294              :
         295            2 :       final Map<String, ScoreStatistics> statistics = {};
         296              :
         297            2 :       if (data['statistics'] != null) {
         298              :         final Map<String, dynamic> statsData =
         299            2 :             data['statistics'] as Map<String, dynamic>;
         300              :
         301            4 :         statsData.forEach((key, value) {
         302              :           if (value != null) {
         303              :             try {
         304            4 :               statistics[key] = ScoreStatistics.fromJson(value);
         305              :             } catch (e) {
         306            0 :               print('통계 변환 오류: $key - $e');
         307              :             }
         308              :           }
         309              :         });
         310              :       }
         311              :
         312              :       return statistics;
         313              :     } catch (e) {
         314            0 :       throw Exception('클럽 통계를 불러오는데 실패했습니다: $e');
         315              :     }
         316              :   }
         317              : }

Generated by: LCOV version 2.3.1-1