refactor: UI 화면 통합 및 불필요한 파일 정리
Some checks failed
Flutter Test & Quality Check / Build APK (push) Has been cancelled
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled

- 모든 *_redesign.dart 파일을 기본 화면 파일로 통합
- 백업용 컨트롤러 파일들 제거 (*_controller.backup.dart)
- 사용하지 않는 예제 및 테스트 파일 제거
- Clean Architecture 적용 후 남은 정리 작업 완료
- 테스트 코드 정리 및 구조 개선 준비

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-08-11 14:00:44 +09:00
parent 162fe08618
commit 1e6da44917
103 changed files with 1224 additions and 2976 deletions

View File

@@ -96,8 +96,9 @@ class CompanyFormController {
try {
List<Company> companies;
// API만 사용
companies = await _companyService.getCompanies();
// API만 사용 (PaginatedResponse에서 items 추출)
final response = await _companyService.getCompanies();
companies = response.items;
companyNames = companies.map((c) => c.name).toList();
filteredCompanyNames = companyNames;
@@ -347,9 +348,9 @@ class CompanyFormController {
if (_useApi) {
try {
// 회사명 목록을 조회하여 중복 확인
final companies = await _companyService.getCompanies(search: name);
final response = await _companyService.getCompanies(search: name);
// 정확히 일치하는 회사명이 있는지 확인
for (final company in companies) {
for (final company in response.items) {
if (company.name.toLowerCase() == name.toLowerCase()) {
return company;
}

View File

@@ -1,331 +0,0 @@
import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/core/errors/failures.dart';
// 회사 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러
class CompanyListController extends ChangeNotifier {
final CompanyService _companyService = GetIt.instance<CompanyService>();
List<Company> companies = [];
List<Company> filteredCompanies = [];
String searchKeyword = '';
final Set<int> selectedCompanyIds = {};
bool _isLoading = false;
String? _error;
// API만 사용
// 페이지네이션
int _currentPage = 1;
int _perPage = 20;
bool _hasMore = true;
// 필터
bool? _isActiveFilter;
// Getters
bool get isLoading => _isLoading;
String? get error => _error;
bool get hasMore => _hasMore;
int get currentPage => _currentPage;
bool? get isActiveFilter => _isActiveFilter;
CompanyListController();
// 초기 데이터 로드
Future<void> initialize() async {
print('╔══════════════════════════════════════════════════════════');
print('║ 🚀 회사 목록 초기화 시작');
print('║ • 페이지 크기: $_perPage개');
print('╚══════════════════════════════════════════════════════════');
await loadData(isRefresh: true);
}
// 페이지 크기를 지정하여 초기화
Future<void> initializeWithPageSize(int pageSize) async {
_perPage = pageSize;
print('╔══════════════════════════════════════════════════════════');
print('║ 🚀 회사 목록 초기화 시작 (커스텀 페이지 크기)');
print('║ • 페이지 크기: $_perPage개');
print('╚══════════════════════════════════════════════════════════');
await loadData(isRefresh: true);
}
// 데이터 로드 및 필터 적용
Future<void> loadData({bool isRefresh = false}) async {
print('🔍 [DEBUG] loadData 시작 - currentPage: $_currentPage, hasMore: $_hasMore, companies.length: ${companies.length}');
print('[CompanyListController] loadData called - isRefresh: $isRefresh');
if (isRefresh) {
_currentPage = 1;
_hasMore = true;
companies.clear();
filteredCompanies.clear();
}
if (_isLoading || (!_hasMore && !isRefresh)) return;
_isLoading = true;
_error = null;
notifyListeners();
try {
// API 호출 - 지점 정보 포함
print('[CompanyListController] Using API to fetch companies with branches');
// 지점 정보를 포함한 전체 회사 목록 가져오기
final apiCompaniesWithBranches = await _companyService.getCompaniesWithBranchesFlat();
// 상세한 회사 정보 로그 출력
print('╔══════════════════════════════════════════════════════════');
print('║ 📊 회사 목록 로드 완료');
print('║ ▶ 총 회사 수: ${apiCompaniesWithBranches.length}');
print('╟──────────────────────────────────────────────────────────');
// 지점이 있는 회사와 없는 회사 구분
int companiesWithBranches = 0;
int totalBranches = 0;
for (final company in apiCompaniesWithBranches) {
if (company.branches?.isNotEmpty ?? false) {
companiesWithBranches++;
totalBranches += company.branches!.length;
print('║ • ${company.name}: ${company.branches!.length}개 지점');
}
}
final companiesWithoutBranches = apiCompaniesWithBranches.length - companiesWithBranches;
print('╟──────────────────────────────────────────────────────────');
print('║ 📈 통계');
print('║ • 지점이 있는 회사: ${companiesWithBranches}');
print('║ • 지점이 없는 회사: ${companiesWithoutBranches}');
print('║ • 총 지점 수: ${totalBranches}');
print('╚══════════════════════════════════════════════════════════');
// 검색어 필터 적용 (서버에서 필터링이 안 되므로 클라이언트에서 처리)
List<Company> filteredApiCompanies = apiCompaniesWithBranches;
if (searchKeyword.isNotEmpty) {
final keyword = searchKeyword.toLowerCase();
filteredApiCompanies = apiCompaniesWithBranches.where((company) {
return company.name.toLowerCase().contains(keyword) ||
(company.contactName?.toLowerCase().contains(keyword) ?? false) ||
(company.contactPhone?.toLowerCase().contains(keyword) ?? false);
}).toList();
print('╔══════════════════════════════════════════════════════════');
print('║ 🔍 검색 필터 적용');
print('║ • 검색어: "$searchKeyword"');
print('║ • 필터 전: ${apiCompaniesWithBranches.length}');
print('║ • 필터 후: ${filteredApiCompanies.length}');
print('╚══════════════════════════════════════════════════════════');
}
// 활성 상태 필터 적용 (현재 API에서 지원하지 않으므로 주석 처리)
// if (_isActiveFilter != null) {
// filteredApiCompanies = filteredApiCompanies.where((c) => c.isActive == _isActiveFilter).toList();
// }
// 전체 데이터를 한 번에 로드 (View에서 페이지네이션 처리)
companies = filteredApiCompanies;
_hasMore = false; // 전체 데이터를 로드했으므로 더 이상 로드할 필요 없음
print('╔══════════════════════════════════════════════════════════');
print('║ 📑 전체 데이터 로드 완료');
print('║ • 로드된 회사 수: ${companies.length}');
print('║ • 필터링된 회사 수: ${filteredApiCompanies.length}');
print('║ • View에서 페이지네이션 처리 예정');
print('╚══════════════════════════════════════════════════════════');
// 필터 적용
applyFilters();
print('╔══════════════════════════════════════════════════════════');
print('║ ✅ 최종 화면 표시');
print('║ • 화면에 표시될 회사 수: ${filteredCompanies.length}');
print('╚══════════════════════════════════════════════════════════');
selectedCompanyIds.clear();
} on Failure catch (e) {
print('[CompanyListController] Failure loading companies: ${e.message}');
_error = e.message;
} catch (e, stackTrace) {
print('[CompanyListController] Error loading companies: $e');
print('[CompanyListController] Error type: ${e.runtimeType}');
print('[CompanyListController] Stack trace: $stackTrace');
_error = '회사 목록을 불러오는 중 오류가 발생했습니다: $e';
} finally {
_isLoading = false;
notifyListeners();
}
}
// 검색 및 필터 적용
void applyFilters() {
filteredCompanies = companies.where((company) {
// 검색어 필터
if (searchKeyword.isNotEmpty) {
final keyword = searchKeyword.toLowerCase();
final matchesName = company.name.toLowerCase().contains(keyword);
final matchesContact = company.contactName?.toLowerCase().contains(keyword) ?? false;
final matchesPhone = company.contactPhone?.toLowerCase().contains(keyword) ?? false;
if (!matchesName && !matchesContact && !matchesPhone) {
return false;
}
}
// 활성 상태 필터 (현재 API에서 지원안함)
// if (_isActiveFilter != null) {
// 추후 API 지원 시 구현
// }
return true;
}).toList();
}
// 검색어 변경
Future<void> updateSearchKeyword(String keyword) async {
searchKeyword = keyword;
if (keyword.isNotEmpty) {
print('╔══════════════════════════════════════════════════════════');
print('║ 🔍 검색어 변경: "$keyword"');
print('╚══════════════════════════════════════════════════════════');
} else {
print('╔══════════════════════════════════════════════════════════');
print('║ ❌ 검색어 초기화');
print('╚══════════════════════════════════════════════════════════');
}
// API 사용 시 새로 조회
await loadData(isRefresh: true);
}
// 활성 상태 필터 변경
Future<void> changeActiveFilter(bool? isActive) async {
_isActiveFilter = isActive;
await loadData(isRefresh: true);
}
// 회사 선택/해제
void toggleCompanySelection(int? companyId) {
if (companyId == null) return;
if (selectedCompanyIds.contains(companyId)) {
selectedCompanyIds.remove(companyId);
} else {
selectedCompanyIds.add(companyId);
}
notifyListeners();
}
// 전체 선택/해제
void toggleSelectAll() {
if (selectedCompanyIds.length == filteredCompanies.length) {
selectedCompanyIds.clear();
} else {
selectedCompanyIds.clear();
for (final company in filteredCompanies) {
if (company.id != null) {
selectedCompanyIds.add(company.id!);
}
}
}
notifyListeners();
}
// 선택된 회사 수 반환
int getSelectedCount() {
return selectedCompanyIds.length;
}
// 회사 삭제
Future<bool> deleteCompany(int companyId) async {
try {
// API를 통한 삭제
await _companyService.deleteCompany(companyId);
// 로컬 리스트에서도 제거
companies.removeWhere((c) => c.id == companyId);
filteredCompanies.removeWhere((c) => c.id == companyId);
selectedCompanyIds.remove(companyId);
notifyListeners();
return true;
} on Failure catch (e) {
_error = e.message;
notifyListeners();
return false;
} catch (e) {
_error = '회사 삭제 중 오류가 발생했습니다: $e';
notifyListeners();
return false;
}
}
// 선택된 회사들 삭제
Future<bool> deleteSelectedCompanies() async {
final selectedIds = selectedCompanyIds.toList();
int successCount = 0;
for (final companyId in selectedIds) {
if (await deleteCompany(companyId)) {
successCount++;
}
}
return successCount == selectedIds.length;
}
// 회사 정보 업데이트 (로컬)
void updateCompanyLocally(Company updatedCompany) {
final index = companies.indexWhere((c) => c.id == updatedCompany.id);
if (index != -1) {
companies[index] = updatedCompany;
applyFilters();
notifyListeners();
}
}
// 회사 추가 (로컬)
void addCompanyLocally(Company newCompany) {
companies.insert(0, newCompany);
applyFilters();
notifyListeners();
}
// 더 많은 데이터 로드
Future<void> loadMore() async {
print('🔍 [DEBUG] loadMore 호출됨 - hasMore: $_hasMore, isLoading: $_isLoading');
if (!_hasMore || _isLoading) {
print('🔍 [DEBUG] loadMore 조건 미충족으로 종료 (hasMore: $_hasMore, isLoading: $_isLoading)');
return;
}
print('🔍 [DEBUG] loadMore 실행 - 추가 데이터 로드 시작');
await loadData();
}
// API만 사용하므로 토글 기능 제거
// 에러 처리
void clearError() {
_error = null;
notifyListeners();
}
// 리프레시
Future<void> refresh() async {
print('╔══════════════════════════════════════════════════════════');
print('║ 🔄 회사 목록 새로고침 시작');
print('╚══════════════════════════════════════════════════════════');
await loadData(isRefresh: true);
}
@override
void dispose() {
super.dispose();
}
}

View File

@@ -48,8 +48,8 @@ class CompanyListController extends BaseListController<Company> {
required PaginationParams params,
Map<String, dynamic>? additionalFilters,
}) async {
// API 호출 - 회사 목록 조회
final apiCompanies = await ErrorHandler.handleApiCall<List<Company>>(
// API 호출 - 회사 목록 조회 (이제 PaginatedResponse 반환)
final response = await ErrorHandler.handleApiCall<dynamic>(
() => _companyService.getCompanies(
page: params.page,
perPage: params.perPage,
@@ -61,21 +61,17 @@ class CompanyListController extends BaseListController<Company> {
},
);
final items = apiCompanies ?? [];
// 임시로 메타데이터 생성 (추후 API에서 실제 메타데이터 반환 시 수정)
// PaginatedResponse를 PagedResult로 변환
final meta = PaginationMeta(
currentPage: params.page,
perPage: params.perPage,
total: items.length < params.perPage ?
(params.page - 1) * params.perPage + items.length :
params.page * params.perPage + 1,
totalPages: items.length < params.perPage ? params.page : params.page + 1,
hasNext: items.length >= params.perPage,
hasPrevious: params.page > 1,
currentPage: response.page,
perPage: response.size,
total: response.totalElements,
totalPages: response.totalPages,
hasNext: !response.last,
hasPrevious: !response.first,
);
return PagedResult(items: items, meta: meta);
return PagedResult(items: response.items, meta: meta);
}
@override