전체 학생 허용 시 장시간(1시간 59분 이상) 요청은 자동 제외

기존엔 전체 승인이 장시간 요청도 구분 없이 다 승인해버렸음. 이제
1시간 59분 넘는 요청은 자동으로 빼고 대기중 상태로 남겨서, "많은
시간요청 학생" 목록에서 따로 검토 후 개별 승인/거절하게 함. 확인
다이얼로그에도 몇 건이 승인되고 몇 건이 제외되는지 미리 보여줌.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 15:03:27 +09:00
co-authored by Claude Sonnet 5
parent 04892d5e65
commit 26e54a1798
2 changed files with 35 additions and 11 deletions
@@ -96,24 +96,37 @@ class DeviceCheckoutLedgerController extends ChangeNotifier {
}); });
} }
/// 🙌 [전체 학생 허용] 대상이 될 요청 id 목록 (대기 중이면서 장시간 요청은 아닌 것만).
/// 확인 다이얼로그에서 몇 건이 승인되고 몇 건이 제외되는지 미리 보여주는 데 쓴다.
List<int> get autoApprovableIds => _requests
.where((r) => r['status'] == 'PENDING' && !isLongRequest(r))
.map<int>((r) => r['id'] as int)
.toList();
// 🙌 [전체 학생 허용] 대기 중인 요청을 한 명씩 누르기 귀찮을 때, 한 번에 전부 승인한다. // 🙌 [전체 학생 허용] 대기 중인 요청을 한 명씩 누르기 귀찮을 때, 한 번에 전부 승인한다.
// 서버에 일괄 승인 API가 따로 없어서, 대기 중인 요청마다 승인 요청을 순서대로 보낸다. // 단, 1시간 59분 넘는 장시간 요청은 자동으로 제외하고 대기중 상태로 남겨서,
// "많은 시간요청 학생" 목록에서 따로 검토/승인하게 한다.
// 서버에 일괄 승인 API가 따로 없어서, 대상 요청마다 승인 요청을 순서대로 보낸다.
Future<(bool success, String message)> approveAllPending({ Future<(bool success, String message)> approveAllPending({
required String teacherId, required String teacherId,
required String teacherName, required String teacherName,
}) async { }) async {
final pendingIds = _requests final targetIds = autoApprovableIds;
.where((r) => r['status'] == 'PENDING') final excludedCount = longPendingRequests.length;
.map<int>((r) => r['id'] as int)
.toList(); if (targetIds.isEmpty) {
if (pendingIds.isEmpty) { return (
return (true, '승인 대기 중인 요청이 없습니다.'); true,
excludedCount > 0
? '장시간 요청 $excludedCount건을 제외하면 승인할 대기 요청이 없습니다.'
: '승인 대기 중인 요청이 없습니다.',
);
} }
_isWorking = true; _isWorking = true;
_safeNotify(); _safeNotify();
int successCount = 0; int successCount = 0;
for (final id in pendingIds) { for (final id in targetIds) {
try { try {
final response = await http.post( final response = await http.post(
Uri.parse('$baseUrl/api/device-checkout/approve'), Uri.parse('$baseUrl/api/device-checkout/approve'),
@@ -136,10 +149,13 @@ class DeviceCheckoutLedgerController extends ChangeNotifier {
_isWorking = false; _isWorking = false;
_safeNotify(); _safeNotify();
final allOk = successCount == pendingIds.length; final allOk = successCount == targetIds.length;
final excludedNote = excludedCount > 0
? ' (장시간 요청 $excludedCount건은 제외 - 대기중으로 남음)'
: '';
return ( return (
allOk, allOk,
'${pendingIds.length}건 중 $successCount건 승인 완료${allOk ? '' : ' (일부 실패)'}', '${targetIds.length}건 중 $successCount건 승인 완료${allOk ? '' : ' (일부 실패)'}$excludedNote',
); );
} }
+9 -1
View File
@@ -50,6 +50,7 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
} }
// 🙌 [전체 학생 허용] 한 명씩 누르기 귀찮을 때, 대기 중인 요청을 한 번에 전부 승인한다. // 🙌 [전체 학생 허용] 한 명씩 누르기 귀찮을 때, 대기 중인 요청을 한 번에 전부 승인한다.
// 1시간 59분 넘는 장시간 요청은 자동으로 제외되어 대기중으로 남는다 - 따로 검토가 필요해서.
void _showApproveAllConfirmDialog() { void _showApproveAllConfirmDialog() {
final pendingCount = _controller.requests final pendingCount = _controller.requests
.where((r) => r['status'] == 'PENDING') .where((r) => r['status'] == 'PENDING')
@@ -58,11 +59,18 @@ class _DeviceCheckoutLedgerPageState extends State<DeviceCheckoutLedgerPage> {
AppNotice.show(context, '승인 대기 중인 요청이 없습니다.'); AppNotice.show(context, '승인 대기 중인 요청이 없습니다.');
return; return;
} }
final approvableCount = _controller.autoApprovableIds.length;
final excludedCount = pendingCount - approvableCount;
showDialog( showDialog(
context: context, context: context,
builder: (dialogContext) => AlertDialog( builder: (dialogContext) => AlertDialog(
title: const Text('전체 학생 허용'), title: const Text('전체 학생 허용'),
content: Text('대기 중인 요청 $pendingCount건을 한 번에 전부 승인하시겠습니까?'), content: Text(
excludedCount > 0
? '대기 중인 요청 $pendingCount건 중 $approvableCount건을 승인합니다.\n'
'장시간(1시간 59분 이상) 요청 $excludedCount건은 제외되어 "많은 시간요청 학생"에서 따로 확인해야 합니다.'
: '대기 중인 요청 $pendingCount건을 한 번에 전부 승인하시겠습니까?',
),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(dialogContext), onPressed: () => Navigator.pop(dialogContext),