diff --git a/lib/function/device_checkout_ledger_controller.dart b/lib/function/device_checkout_ledger_controller.dart index c942bfa..9ba4d34 100644 --- a/lib/function/device_checkout_ledger_controller.dart +++ b/lib/function/device_checkout_ledger_controller.dart @@ -16,25 +16,38 @@ class DeviceCheckoutLedgerController extends ChangeNotifier { bool get isLoading => _isLoading; bool get isWorking => _isWorking; - /// ⏰ 요청 시간이 얼마나 되는지(시간 단위). 형식이 이상하면 null. - double? durationHours(dynamic request) { + // 🚨 [장시간 요청 기준] 1시간 59분(119분) 이상이면 "많은 시간요청"으로 본다. + static const int longRequestMinutes = 119; + + int? _durationMinutes(dynamic request) { try { final start = DateTime.parse(request['requestedStart']); final end = DateTime.parse(request['requestedEnd']); final minutes = end.difference(start).inMinutes; - return minutes > 0 ? minutes / 60.0 : null; + return minutes > 0 ? minutes : null; } catch (_) { return null; } } - /// 🚨 [장시간 요청 감지] 2시간 넘게 신청한, 아직 대기 중인 요청 목록. - /// 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니 전체 승인 전에 따로 훑어볼 수 있게 한다. - List get longPendingRequests => _requests.where((r) { - if (r['status'] != 'PENDING') return false; - final hours = durationHours(r); - return hours != null && hours >= 2; - }).toList(); + /// ⏰ 요청 시간이 얼마나 되는지(시간 단위). 형식이 이상하면 null. + double? durationHours(dynamic request) { + final minutes = _durationMinutes(request); + return minutes == null ? null : minutes / 60.0; + } + + /// 🚨 [장시간 요청 감지] 1시간 59분 넘게 신청했는지. 상태(대기/승인 등)와 무관하게 판단한다 - + /// 목록 카드에 빨간 테두리를 씌우는 데 쓴다. + bool isLongRequest(dynamic request) { + final minutes = _durationMinutes(request); + return minutes != null && minutes >= longRequestMinutes; + } + + /// 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니, 아직 대기 중인 장시간 요청만 + /// 따로 모아서 전체 승인 전에 훑어볼 수 있게 한다. + List get longPendingRequests => _requests + .where((r) => r['status'] == 'PENDING' && isLongRequest(r)) + .toList(); void _safeNotify() { if (!_disposed) notifyListeners(); diff --git a/lib/ui/device_checkout_ledger_page.dart b/lib/ui/device_checkout_ledger_page.dart index 3090715..bcce350 100644 --- a/lib/ui/device_checkout_ledger_page.dart +++ b/lib/ui/device_checkout_ledger_page.dart @@ -89,7 +89,7 @@ class _DeviceCheckoutLedgerPageState extends State { ); } - // 🚨 [많은 시간요청 학생] 2시간 넘게 신청한 대기 중인 요청만 따로 모아 보여준다. + // 🚨 [많은 시간요청 학생] 1시간 59분 넘게 신청한 대기 중인 요청만 따로 모아 보여준다. // 학생이 시간을 비정상적으로 길게 적어냈을 수 있으니, 전체 승인 전에 훑어보는 용도. void _showLongRequestsDialog() { showDialog( @@ -113,7 +113,7 @@ class _DeviceCheckoutLedgerPageState extends State { return const Padding( padding: EdgeInsets.symmetric(vertical: 16), child: Text( - '2시간 넘게 신청한 대기 중인 요청이 없습니다.', + '1시간 59분 넘게 신청한 대기 중인 요청이 없습니다.', style: TextStyle(color: Colors.grey), ), ); @@ -320,6 +320,10 @@ class _DeviceCheckoutLedgerPageState extends State { final String status = r['status']; final info = _statusInfo(status); final bool isPending = status == 'PENDING'; + // 🚨 1시간 59분 넘게 신청했으면 상태와 무관하게 빨간 테두리로 눈에 띄게. + final bool isLong = _controller.isLongRequest( + r, + ); return Card( elevation: 0, @@ -327,9 +331,18 @@ class _DeviceCheckoutLedgerPageState extends State { margin: const EdgeInsets.only(bottom: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), - side: isPending - ? BorderSide(color: Colors.orange[300]!) - : BorderSide(color: AppPalette.sage), + side: isLong + ? BorderSide( + color: Colors.red[400]!, + width: 2, + ) + : (isPending + ? BorderSide( + color: Colors.orange[300]!, + ) + : BorderSide( + color: AppPalette.sage, + )), ), child: Padding( padding: const EdgeInsets.all(16),