스마트기기 반출 대장: 1시간 59분 이상 요청은 목록에서 빨간 테두리로 표시

기존엔 "많은 시간요청 학생" 팝업에서만 2시간 기준으로 걸러냈는데,
메인 목록 카드 자체에도 (대기중/승인/거절 등 상태 무관하게) 빨간
테두리를 씌워서 바로 눈에 띄게 함. 기준을 2시간 → 1시간 59분(119분)으로
낮춰서 두 기능이 같은 기준을 쓰도록 통일.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 08:31:10 +09:00
co-authored by Claude Sonnet 5
parent a3894cc878
commit 04892d5e65
2 changed files with 41 additions and 15 deletions
@@ -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<dynamic> 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<dynamic> get longPendingRequests => _requests
.where((r) => r['status'] == 'PENDING' && isLongRequest(r))
.toList();
void _safeNotify() {
if (!_disposed) notifyListeners();