String? fetchPathOf(Map row) { final forced = '${row['_fetch'] ?? ''}'; if (forced.startsWith('/')) return forced; final id = '${row['id'] ?? ''}'; final bizId = '${row['bizId'] ?? ''}'; final source = '${row['source'] ?? ''}'; final kind = '${row['kind'] ?? ''}'; final biz = '${row['bizType'] ?? ''}'; final path = '${row['path'] ?? ''}'; if (source == 'EXPENSE' && kind == 'LOAN' && id.isNotEmpty) return '/loans/$id'; if (source == 'EXPENSE' && id.isNotEmpty) return '/expenses/$id'; if (source == 'HR' && id.isNotEmpty) return '/leave-requests/$id'; if (source == 'OFFICE' && id.isNotEmpty) return '/office/applies/$id'; if (source == 'SEAL' && id.isNotEmpty) return '/seal-requests/$id'; if (bizId.isNotEmpty) { if (biz == 'EXPENSE_APPROVAL' || biz == 'EXPENSE_DRAFT' || biz == 'TRAVEL_EXPENSE') return '/expenses/$bizId'; if (biz == 'LOAN_APPROVAL' || biz == 'LOAN_OFFSET') return '/loans/$bizId'; if (biz == 'HR_LEAVE') return '/leave-requests/$bizId'; if (biz == 'OFFICE_APPLY') return '/office/applies/$bizId'; if (biz == 'SEAL_APPROVAL' || biz == 'SEAL_RETURN' || biz == 'SEAL_REQUEST') return '/seal-requests/$bizId'; if (biz.startsWith('BID')) return '/bid-cases/$bizId'; if (biz.startsWith('CONTRACT')) return '/contracts/$bizId'; if (biz == 'WORK_REPORT') return '/office/reports/$bizId'; if (biz == 'WORK_ASSIGN') return null; if (biz.startsWith('PROJECT')) return '/projects/$bizId'; } if (row['expense'] is Map) return '/expenses/${(row['expense'] as Map)['id']}'; if (row['loan'] is Map) return '/loans/${(row['loan'] as Map)['id']}'; if (row['leaveRequest'] is Map) return '/leave-requests/${(row['leaveRequest'] as Map)['id']}'; if (row['officeApply'] is Map) return '/office/applies/${(row['officeApply'] as Map)['id']}'; if (row['sealRequest'] is Map) return '/seal-requests/${(row['sealRequest'] as Map)['id']}'; if (row['contract'] is Map) return '/contracts/${(row['contract'] as Map)['id']}'; if (row['bidCase'] is Map) return '/bid-cases/${(row['bidCase'] as Map)['id']}'; if (row['project'] is Map) return '/projects/${(row['project'] as Map)['id']}'; if (path.startsWith('/office/expenses/') && path.length > 17) return '/expenses/${path.split('/').last}'; if (path.startsWith('/office/loans/') && path.length > 14) return '/loans/${path.split('/').last}'; if (id.length == 36) { if (row.containsKey('claimNo') || row.containsKey('expenseCategory')) return '/expenses/$id'; if (row.containsKey('loanNo') || kind == 'LOAN') return '/loans/$id'; if (row.containsKey('bidNo') || row.containsKey('externalNo')) return '/bid-cases/$id'; if (row.containsKey('contractNo')) return '/contracts/$id'; if (row.containsKey('projectNo')) return '/projects/$id'; if (row.containsKey('sealType') || row.containsKey('takeOut')) return '/seal-requests/$id'; } return null; } String detailTitleOf(Map row) { for (final k in [ 'title', 'name', 'purpose', 'reason', 'claimNo', 'loanNo', 'bidNo', 'contractNo', 'projectName' ]) { final v = row[k]; if (v != null && '$v'.trim().isNotEmpty) return '$v'; } return '详情'; }