fix: 페이지네이션 로직 개선 및 상세 로그 추가
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

- 모든 관리 화면(회사, 장비, 입고지, 유지보수)의 페이지네이션 로직 통일
- Controller에서 전체 데이터 로드, View에서만 페이지네이션 처리
- 각 화면에 상세한 터미널 로그 추가로 데이터 로드 상태 추적 가능
- 회사 DTO에 지점 정보 포함 기능 추가
- 전체 79개 회사 중 14개만 표시되던 문제 해결
This commit is contained in:
JiWoong Sul
2025-08-09 19:40:39 +09:00
parent c49f6a1696
commit 7d0077cd57
16 changed files with 566 additions and 150 deletions

View File

@@ -253,6 +253,14 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
final int startIndex = (_currentPage - 1) * _pageSize;
final int endIndex = startIndex + _pageSize;
// 디버그 로그 추가
print('🔍 [VIEW DEBUG] 화면 페이지네이션 상태');
print(' • filteredCompanies 수: ${controller.filteredCompanies.length}');
print(' • displayCompanies 수: ${displayCompanies.length}개 (지점 포함)');
print(' • 현재 페이지: $_currentPage');
print(' • 페이지 크기: $_pageSize');
print(' • startIndex: $startIndex, endIndex: $endIndex');
// startIndex가 displayCompanies.length보다 크거나 같으면 첫 페이지로 리셋
if (startIndex >= displayCompanies.length && displayCompanies.isNotEmpty) {
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -265,9 +273,11 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
final List<Map<String, dynamic>> pagedCompanies = displayCompanies.isEmpty
? []
: displayCompanies.sublist(
startIndex.clamp(0, displayCompanies.length - 1),
startIndex.clamp(0, displayCompanies.length),
endIndex.clamp(0, displayCompanies.length),
);
print(' • 화면에 표시될 항목 수: ${pagedCompanies.length}');
// 로딩 상태
if (controller.isLoading && controller.companies.isEmpty) {

View File

@@ -38,17 +38,26 @@ class CompanyListController extends ChangeNotifier {
// 초기 데이터 로드
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) {
@@ -71,15 +80,34 @@ class CompanyListController extends ChangeNotifier {
// 지점 정보를 포함한 전체 회사 목록 가져오기
final apiCompaniesWithBranches = await _companyService.getCompaniesWithBranchesFlat();
print('[CompanyListController] API returned ${apiCompaniesWithBranches.length} companies with branches');
// 지점 수 출력
// 상세한 회사 정보 로그 출력
print('╔══════════════════════════════════════════════════════════');
print('║ 📊 회사 목록 로드 완료');
print('║ ▶ 총 회사 수: ${apiCompaniesWithBranches.length}');
print('╟──────────────────────────────────────────────────────────');
// 지점이 있는 회사와 없는 회사 구분
int companiesWithBranches = 0;
int totalBranches = 0;
for (final company in apiCompaniesWithBranches) {
if (company.branches?.isNotEmpty ?? false) {
print('[CompanyListController] ${company.name} has ${company.branches?.length ?? 0} branches');
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) {
@@ -89,6 +117,13 @@ class CompanyListController extends ChangeNotifier {
(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에서 지원하지 않으므로 주석 처리)
@@ -96,30 +131,36 @@ class CompanyListController extends ChangeNotifier {
// filteredApiCompanies = filteredApiCompanies.where((c) => c.isActive == _isActiveFilter).toList();
// }
// 페이지네이션 처리 (클라이언트 사이드)
final startIndex = (_currentPage - 1) * _perPage;
final endIndex = startIndex + _perPage;
final paginatedCompanies = filteredApiCompanies.skip(startIndex).take(_perPage).toList();
// 전체 데이터를 한 번에 로드 (View에서 페이지네이션 처리)
companies = filteredApiCompanies;
_hasMore = false; // 전체 데이터를 로드했으므로 더 이상 로드할 필요 없음
if (isRefresh) {
companies = paginatedCompanies;
} else {
companies.addAll(paginatedCompanies);
}
_hasMore = endIndex < filteredApiCompanies.length;
if (_hasMore) _currentPage++;
print('╔══════════════════════════════════════════════════════════');
print('║ 📑 전체 데이터 로드 완료');
print('║ • 로드된 회사 수: ${companies.length}');
print('║ • 필터링된 회사 수: ${filteredApiCompanies.length}');
print('║ • View에서 페이지네이션 처리 예정');
print('╚══════════════════════════════════════════════════════════');
} else {
// Mock 데이터 사용
print('[CompanyListController] Using Mock data');
companies = dataService.getAllCompanies();
print('[CompanyListController] Mock returned ${companies.length} companies');
print('╔══════════════════════════════════════════════════════════');
print('║ 🔧 Mock 데이터 로드 완료');
print('║ ▶ 총 회사 수: ${companies.length}');
print('╚══════════════════════════════════════════════════════════');
_hasMore = false;
}
// 필터 적용
applyFilters();
print('[CompanyListController] After filtering: ${filteredCompanies.length} companies shown');
print('╔══════════════════════════════════════════════════════════');
print('║ ✅ 최종 화면 표시');
print('║ • 화면에 표시될 회사 수: ${filteredCompanies.length}');
print('╚══════════════════════════════════════════════════════════');
selectedCompanyIds.clear();
} on Failure catch (e) {
print('[CompanyListController] Failure loading companies: ${e.message}');
@@ -165,6 +206,17 @@ class CompanyListController extends ChangeNotifier {
// 검색어 변경
Future<void> updateSearchKeyword(String keyword) async {
searchKeyword = keyword;
if (keyword.isNotEmpty) {
print('╔══════════════════════════════════════════════════════════');
print('║ 🔍 검색어 변경: "$keyword"');
print('╚══════════════════════════════════════════════════════════');
} else {
print('╔══════════════════════════════════════════════════════════');
print('║ ❌ 검색어 초기화');
print('╚══════════════════════════════════════════════════════════');
}
if (_useApi) {
// API 사용 시 새로 조회
await loadData(isRefresh: true);
@@ -275,7 +327,12 @@ class CompanyListController extends ChangeNotifier {
// 더 많은 데이터 로드
Future<void> loadMore() async {
if (!_hasMore || _isLoading || !_useApi) return;
print('🔍 [DEBUG] loadMore 호출됨 - hasMore: $_hasMore, isLoading: $_isLoading, useApi: $_useApi');
if (!_hasMore || _isLoading || !_useApi) {
print('🔍 [DEBUG] loadMore 조건 미충족으로 종료 (hasMore: $_hasMore, isLoading: $_isLoading, useApi: $_useApi)');
return;
}
print('🔍 [DEBUG] loadMore 실행 - 추가 데이터 로드 시작');
await loadData();
}
@@ -293,6 +350,9 @@ class CompanyListController extends ChangeNotifier {
// 리프레시
Future<void> refresh() async {
print('╔══════════════════════════════════════════════════════════');
print('║ 🔄 회사 목록 새로고침 시작');
print('╚══════════════════════════════════════════════════════════');
await loadData(isRefresh: true);
}